2

I have a Jenkins slave running on macOS via ssh slave, then screen, then launching following script, which makes sure to reconnect the server if it goes down:

#!/usr/bin/env bash

function startSlave() {
  java -jar /Users/user/slave.jar -jnlpUrl https://jenkins.company.com/computer/slave-office/slave-agent.jnlp -secret xyz
  sleep 3
}

startSlave

while true; do
  PID=$(pgrep "slave-agent.jnlp" | awk '{print $2}')
  if [[ -z $PID ]]; then
    echo "Jenkins slave has died, restarting..."
    startSlave
  fi
  sleep 60
done

This works great, echo $PATH in a Jenkins job equals the same as running echo $PATH in a terminal session that is opened via ssh.

Sometimes we need to reboot the machine though, so I want this script to be executed on login. I tested starting the script via launchctl solution and and App that is in macOS user startup application list.

Both times echo $PATH of the Jenkins slave simply equals: /usr/bin:/bin:/usr/sbin:/sbin Hence the PATH is not correctly set from the currently logged in user.

  • The process is running under the users accounts
  • Even the process that Jenkins slave kicks of runs under the users account
  • We use only ~/.profile to set up the environment vars...

What's wrong? Why does Jenkins slave not correctly setup the PATH variable when I launch the above script via launchctl or Application?

UPDATE: I got it working by explicitly sourcing profile in the Jenkins job: source /Users/leanplumbuild/.profile Does anyone know why Jenkins-Slave is not doing this automatically?

1 Answers1

6

I don't know for sure, but my first guess is that this is because Jenkins is not launching the subshell as a 'login shell'. When you log into a shell in an interactive environment, the shell loads environment files differently than when it is launched via a 'non-interactive' environment, like cron. To change this behavior, and make your environments 'match' with more fidelity, you'll need to launch the subshell as a login shell. There are various ways to do this, and I'm sure Jenkins has a way that is more robust, but, at a minimum, you can try to change the first sh-bang line to:

#!/bin/bash -l

Remove that explicit sourcing line from the job. Now, see if everything works! :)

For reference, take a look at the long and complex section of the bash man page "INVOCATION". https://linux.die.net/man/1/bash

Jesse Adelman
  • 978
  • 5
  • 15