Jenkins / Hudson environment variables
Asked Answered
J

22

108

I am running Jenkins from user jenkins thats has $PATH set to something and when I go into Jenkins web interface, in the System Properties window (http://$host/systemInfo) I see a different $PATH.

I have installed Jenkins on Centos with the native rpm from Jenkins website. I am using the startup script provided with the installation using sudo /etc/init.d/jenkins start

Can anyone please explain to me why that happens?

Jujutsu answered 28/4, 2011 at 12:12 Comment(4)
If you login as jenkins, and echo $PATH, does it match what you see in jenkins?Pileate
@Dave no, it doesnt match. can't understand whyJujutsu
The reason it doesn't match is because when you login as the jenkins user you're invoking a login shell, whereas jenkins just executes /bin/sh -xe {your script} so it doesn't run through the same set of scripts that alter the PATH environment variable. In fact, the set of scripts does vary according to the particular flavour of *nix and/or shell that you have installed. I've tested on AWS Linux AMI with jenkins and sadly none of /etc/profile /etc/profile.d/xxx.sh /etc/bashrc /etc/environment ~/.bash_profile ~/.profile ~/.bashrc were able to affect the PATH passed to /bin/shAvalon
I did a much simpler change, adding it here since it is not stated in any of the answers. STEP1 : Run this command in your jenkins slave which aws , it will return a value similar to /usr/local/bin/aws . STEP2 : In your groovy script where you are making the CLI call, instead of aws just use /usr/local/bin/aws and it overrides all the other variables. I recommend this instead of modifying files inside the slave or jenkins global parameters.Talesman
B
152

Michael,

Two things:

When Jenkins connects to a computer, it goes to the sh shell, and not the bash shell (at least this is what I have noticed - I may be wrong). So any changes you make to $PATH in your bashrc file are not considered.

Also, any changes you make to $PATH in your local shell (one that you personally ssh into) will not show up in Jenkins.

To change the path that Jenkins uses, you have two options (AFAIK):

1) Edit your /etc/profile file and add the paths that you want there

2) Go to the configuration page of your slave, and add environment variable PATH, with value: $PATH:/followed-by/paths/you/want/to/add

If you use the second option, your System Information will still not show it, but your builds will see the added paths.

Bandoleer answered 28/4, 2011 at 13:55 Comment(10)
This answer worked for me, but I noticed that Jenkins is very sensitive about what you write into the configuration page. I couldn't get it to work with paths with spaces.Hovis
Yes it is, but when you enter paths with spaces in a UNIX shell, the space is normally escaped with a `` character. Therefore, if your path is "/opt/bin/My Folder Name", you may want to try "/opt/bin/My\ Folder\ Name" instead. This will escape the spaces and allow you to use them.Bandoleer
The solution 2 is the way to go.Axinomancy
When I use solution #1, it does not seem to affect the job environment. When I use solution #2, every element of the PATH gets duplicated... which is better than nothing, I suppose. So far, none of the seemingly obvious candidates work on my Ubuntu 13.04 machine (not /etc/profile, or /var/lib/jenkins/.profile, or adding it to the init script, or ... well, I'm sort of worn out looking for places that might actually work without this duplication.Mandrel
Follow-up: on my Ubuntu system, the jenkins service is an upstart job, so I was modifying the old sysvinit stub script. Wrong place. When I tweak the /etc/init/jenkins.conf script, and update the PATH before it exec's java, that does seem to work.Mandrel
@Mandrel after editing your /etc/profile, you must restart your system, since this file is read in only at boot time. If it still does not work after you restart, for whatever reason that file is not being read - which would be really weird for a Linux system.Bandoleer
Oh, good point. I didn't even think that far about it. I was assuming that Jenkins was using some internal logic to setup the PATH or whatever. So probably /etc/profile would be a good general recommendation, as long as the "reboot after!" instruction is included.Mandrel
There is a small dark corner: The jenkins master caches the environment variables from slaves in order to patch the customizations. So if you change environment variables on a slave (system or user), you need to restart the master to update the slaves config.Lowther
Any idea how to make Jenkins go to bash instead of sh?Orphaorphan
@octavian not sure what you mean by "make Jenkins go to bash". @octavian if you go to "Manage Jenkins", there's a configuration box with the field name "Shell executable". You can add the path to bash in there. However, that will set the default shell, which means if your slave does not have bash in that exact location, you will get errors. I would only recommend this if all your slave nodes are LinuxBandoleer
O
39

I kept running into this problem, but now I just add:

source /etc/profile

As the first step in my build process. Now all my subsequent rules are loaded for Jenkins to operate smoothly.

Overlong answered 5/1, 2012 at 22:11 Comment(5)
Huh? In detail, please... you add where? how? when? Does it work on Windows?Catawba
I assume you're running a shell command as part of your build. Put source /etc/profile as the first command in that Build > Execute Shell > Command textarea.Overlong
It works on Mac, also I found paths like /usr/local/bin is specified in /etc/paths, and /etc/paths is used by /usr/libexec/path_helper, and path_helper is executed in /etc/profile.Pion
you saved my day :)Daily
Sourcing /etc/profile does show the path when adding a debug of 'echo $PATH' in the job, but if I look at the environment variables for the job it is not the same.Merovingian
I
26

You can also edit the /etc/sysconfig/jenkins file to make any changes to the environment variables, etc. I simply added source /etc/profile to the end of the file. /etc/profile has all of the proper PATH variables setup. When you do this, make sure you restart Jenkins

/etc/init.d/jenkins restart

We are running ZendServer CE which installs pear, phing, etc in a different path so this was helpful. Also, we don't get the LD_LIBRARY_PATH errors we used to get with Oracle client and Jenkins.

Isa answered 21/1, 2012 at 0:54 Comment(2)
This is a key comment, or restart jenkins from {jenkins-url}/restart or {jenkins-url}/safeRestart . I was banging my head on why path changes were not picked up, by editing even /etc/environment on ubuntu host - RESTART will fix it, as verified by {jenkins-url}/systemInfoCragsman
All the others failed, this is the only one what worked! I wish it were more prevalent so I would not have wasted the last few hours!Jesusitajet
E
17

I tried /etc/profile, ~/.profile and ~/.bash_profile and none of those worked. I found that editing ~/.bashrc for the jenkins slave account did.

Everything answered 27/1, 2012 at 5:13 Comment(1)
that's because non-login shell doesn't read neither /etc/profile nor ~/.profileTestate
C
9

The information on this answer is out of date. You need to go to Configure Jenkins > And you can then click to add an Environment Variable key-value pair from there.

eg: export MYVAR=test would be MYVAR is the key, and test is the value.

Chino answered 30/8, 2012 at 20:58 Comment(0)
S
5

I found two plugins for that. One loads the values from a file and the other lets you configure the values in the job configuration screen.

Envfile Plugin — This plugin enables you to set environment variables via a file. The file's format must be the standard Java property file format.

EnvInject Plugin — This plugin makes it possible to add environment variables and execute a setup script in order to set up an environment for the Job.

Signore answered 22/12, 2011 at 7:28 Comment(0)
M
5

On my newer EC2 instance, simply adding the new value to the Jenkins user's .profile's PATH and then restarting tomcat worked for me.

On an older instance where the config is different, using #2 from Sagar's answer was the only thing that worked (i.e. .profile, .bash* didn't work).

Montcalm answered 16/6, 2012 at 1:30 Comment(0)
F
4

Couldn't you just add it as an environment variable in Jenkins settings:

Manage Jenkins -> Global properties > Environment variables: And then click "Add" to add a property PATH and its value to what you need.

Forcemeat answered 17/11, 2014 at 3:47 Comment(1)
Seems to be "Manage Jenkins -> Configure System -> Environment Variables" in version 1.620.Purificator
E
4

This is how I solved this annoying issue:

I changed the PATH variable as @sagar suggested in his 2nd option, but still I got different PATH value than I expected.

Eventually I found out that it was the EnvInject plugin that replaced my PATH variable!

So I could either uninstall EnvInject or just use it to inject the PATH variable.

As many of our Jenkins jobs use that plugin, I didn't want to uninstall it...

So I created a file: environment_variables.properties under my Jenkins home directory.

This file contained the path environment value that I needed: PATH=$PATH:/usr/local/git/bin/.

From the Jenkins web interface: Manage Jenkins -> Configure System. In that screen - I ticked the Prepare jobs environment option, and in the Properties File Path field I entered the path to my file: /var/lib/jenkins/environment_variables.properties.

This way every Jenkins job we have receive whatever variables I put in this environment_variables.properties file.

Earthwork answered 8/6, 2016 at 10:57 Comment(1)
This should be the correct answer. As stated updating /etc/profile is not a feasible solution on OSX as the file is read only and requires messing around with permissions. This solution seems the cleanest and utilises already existing plugins on Jenkins. Remember to restart jenkins once you create your properties file and set it on JenkinsMyca
W
3

Jenkins also supports the format PATH+<name> to prepend to any variable, not only PATH:

Global Environment variables or node Environment variables:

Jenkins variable + notation

This is also supported in the pipeline step withEnv:

node {
  withEnv(['PATH+JAVA=/path/to/java/bin']) {
    ...
  }
}

Just take note, it prepends to the variable. If it must be appended you need to do what the other answers show.

See the pipeline steps document here.

You may also use the syntax PATH+WHATEVER=/something to prepend /something to $PATH

Or the java docs on EnvVars here.

Wotan answered 11/7, 2018 at 9:26 Comment(0)
H
2

I only had progress on this issue after a "/etc/init.d/jenkins force-reload". I recommend trying that before anything else, and using that rather than restart.

Hauptmann answered 16/8, 2013 at 6:3 Comment(1)
And where did you actually add the PATH element? I've tried every place I can imagine.Mandrel
M
2

On my Ubuntu 13.04, I tried quite a few tweaks before succeeding with this:

  1. Edit /etc/init/jenkins.conf
  2. Locate the spot where "exec start-stop-server..." begins
  3. Insert the environment update just before that, i.e.

export PATH=$PATH:/some/new/path/bin

Mandrel answered 2/1, 2014 at 16:42 Comment(0)
D
2

Add

/usr/bin/bash

at

Jenkins -> Manage Jenkins -> configure System -> Shell->Shell executable

Jenkins use the sh so that even /etc/profile doesn't work for me When I add this, I have all the env.

Decapitate answered 20/12, 2016 at 13:58 Comment(1)
What version of Jenkins did this work for you @sumang_87? It failed to help me on Jenkins 2.9Mussolini
T
1

Solution that worked for me

source ~/.bashrc

Explanation

I first verified Jenkins was running BASH, with echo $SHELL and echo $BASH (note I'm explicitly putting #!/bin/bash atop the textarea in Jenkins, I'm not sure if that's a requirement to get BASH). sourceing /etc/profile as others suggested was not working.

Looking at /etc/profile I found

if [ "$PS1" ]; then
...

and inspecting "$PS1" found it null. I tried spoofing $PS1 to no avail like so

export PS1=1
bash -c 'echo $PATH'

however this did not produce the desired result (add the rest of the $PATH I expect to see). But if I tell bash to be interactive

export PS1=1
bash -ci 'echo $PATH'

the $PATH was altered as I expected.

I was trying to figure out how to properly spoof an interactive shell to get /etc/bash.bashrc to load, however it turns out all I needed was down in ~/.bashrc, so simply sourceing it solved the problem.

Timtima answered 1/4, 2014 at 4:47 Comment(1)
Make sure to use #!/bin/bash -el to tell bash to start up as a login shell. That should cause bash to source the necessary .rc filesBloodstained
L
1

I tried all the things from above - didn't work for me.

I found two solution (both for SSH-Slave)

  1. Go to the slave settings

  2. Add a new environment variable

  3. PATH
  4. ${PATH}:${HOME}/.pub-cache/bin:${HOME}/.local/bin

The "${HOME}" part is important. This makes the additional PATH absolute. Relative path did not work for me.

Option II (pipeline-script)

pipeline {
    agent {
        label 'your-slave'
    }
    environment {
        PATH = "/home/jenkins/.pub-cache/bin:$PATH"
    }
    stages {
        stage('Test') {
            steps {
                ansiColor('xterm') {
                    echo "PATH is: $PATH"
                }
            }
        }
    }
}
Lehmbruck answered 30/11, 2017 at 11:59 Comment(0)
V
0

On Ubuntu I just edit /etc/default/jenkins and add source /etc/profile at the end and it works to me.

Verger answered 21/1, 2014 at 19:7 Comment(0)
C
0

Running the command with environment variable set is also effective. Of course, you have to do it for each command you run, but you probably have a job script, so you probably only have one command per build. My job script is a python script that uses the environment to decide which python to use, so I still needed to put /usr/local/bin/python2.7 in its path:

PATH=/usr/local/bin <my-command>
Culley answered 14/2, 2014 at 22:49 Comment(0)
H
0

What worked for me was overriding the PATH environment for the slave.

Set:   PATH 
To:    $PATH:/usr/local/bin

Then disconnecting and reconnecting the slave.

Despite what the system information was showing it worked.

Hemstitch answered 18/2, 2014 at 7:35 Comment(0)
S
0

I have Jenkins 1.639 installed on SLES 11 SP3 via zypper (the package manager). Installation configured jenkins as a service

 # service jenkins
 Usage: /etc/init.d/jenkins {start|stop|status|try-restart|restart|force-reload|reload|probe}

Although /etc/init.d/jenkins sources /etc/sysconfig/jenkins, any env variables set there are not inherited by the jenkins process because it is started in a separate login shell with a new environment like this:

startproc -n 0 -s -e -l /var/log/jenkins.rc -p /var/run/jenkins.pid -t 1 /bin/su -l -s /bin/bash -c '/usr/java/default/bin/java -Djava.awt.headless=true -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war --javaHome=/usr/java/default --logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war --httpPort=8080 --ajp13Port=8009 --debug=9 --handlerCountMax=100 --handlerCountMaxIdle=20 &' jenkins

The way I managed to set env vars for the jenkins process is via .bashrc in its home directory - /var/lib/jenkins. I had to create /var/lib/jenkins/.bashrc as it did not exist before.

Sabin answered 3/12, 2015 at 10:12 Comment(0)
H
0

1- add to your profil file".bash_profile" file

it is in "/home/your_user/" folder

vi .bash_profile

add:

export JENKINS_HOME=/apps/data/jenkins  
export PATH=$PATH:$JENKINS_HOME

==> it's the e jenkins workspace

2- If you use jetty : go to jenkins.xml file

and add :

<Arg>/apps/data/jenkins</Arg>
Hangeron answered 3/1, 2018 at 18:6 Comment(0)
C
0

Here is what i did on ubuntu 18.04 LTS with Jenkins 2.176.2

I created .bash_aliases file and added there path, proxy variables and so on.

In beginning of .bashrc there was this defined.

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

So it's checking that if we are start non-interactive shell then we don't do nothing here.

bottom of the .bashrc there was include for .bash_aliases

# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

so i moved .bash_aliases loading first at .bashrc just above non-interactive check.

This didn't work first but then i disconnected slave and re-connected it so it's loading variables again. You don't need to restart whole jenkins if you are modifying slave variables. just disconnect and re-connect.

Cove answered 17/9, 2019 at 5:54 Comment(0)
C
0

If your pipeline is executed on the remote node that is connected via SSH, then actually Jenkins runs agent application that performs incoming actions.

By default zsh shell is used, not the bash (my Jenkins has version 2.346.3).

Furthermore jenkins-agent runs non-login shell which makes default PATH values even if you put some configuration to .zshrc. It will be skipped.

My choice is to put the following shebang at a script start

#!/bin/bash -l

-l option makes bash to run in the login mode and in this case bash performs configurations specified in /etc/profile and ~/.bash_profile.

If you run script in Jenkins pipeline it will look like:

steps {
  sh '''#!/bin/bash -l
    env
  '''
}
Conchoidal answered 8/9, 2022 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.