What would be the way to determine the current OS a Jenkins pipeline is running?
Context: I'm building a shared Jenkins pipeline script that should run on all platforms (windows, OSX, linux) and execute something different in each platform.
I tried something like:
import org.apache.commons.lang.SystemUtils
if (SystemUtils.IS_OS_WINDOWS){
bat("Command")
}
if (SystemUtils.IS_OS_MAC){
sh("Command")
}
if (SystemUtils.IS_OS_LINUX){
sh("Command")
}
But even it is running on windows or mac node
it always goes into the SystemUtils.IS_OS_LINUX
branch
I tried a quick pipeline like this.
node('windows ') {
println ('## OS ' + System.properties['os.name'])
}
node('osx ') {
println ('## OS ' + System.properties['os.name'])
}
node('linux') {
println ('## OS ' + System.properties['os.name'])
}
Each node get correctly run in a machine with the correct OS but all of them print ## OS Linux
any ideas?
Thanks Fede
As far as I know Jenkins only differentiates between windows and unix, i.e. if on windows, use bat, on unix/mac/linux, use sh. So you could use isUnix()
, more info here, to determine if you're on unix or windows, and in the case of unix use sh and @Spencer Malone's answer to prope more information about that system (if needed).
Assuming you have Windows as your only non-unix platform, you can use the pipeline function isUnix()
and uname
to check on which Unix OS you're on:
def checkOs(){
if (isUnix()) {
def uname = sh script: 'uname', returnStdout: true
if (uname.startsWith("Darwin")) {
return "Macos"
}
// Optionally add 'else if' for other Unix OS
else {
return "Linux"
}
}
else {
return "Windows"
}
}
Using Java classes is probably not the best approach. I'm pretty sure that unless it's a jenkins / groovy plugin, those run on the master Jenkins JVM thread. I would look into a shell approach, such as the one outlined here: https://stackoverflow.com/a/8597411/5505255
You could wrap that script in a shell step to get the stdout like so:
def osName = sh(script: './detectOS', returnStdout: true)
to call a copy of the script being outlined above. Then just have that script return the OS names you want, and branch logic based on the osName var.
The workaround I found for this is
try{
sh(script: myScript, returnStdout: true)
}catch(Exception ex) {
//assume we are on windows
bat(script: myScript, returnStdout: true)
}
Or a little bit more elegant solution without using the try/catch
is to use the env.NODE_LABELS
. Assuming you have all the nodes correctly labelled you can write a function like this
def isOnWindows(){
def os = "windows"
def List nodeLabels = NODE_LABELS.split()
for (i = 0; i <nodeLabels.size(); i++)
{
if (nodeLabels[i]==os){
return true
}
}
return false
}
and then
if (isOnWindows()) {
def osName = bat(script: command, returnStdout: true)
} else {
def osName = sh(script: command, returnStdout: true)
}
来源:https://stackoverflow.com/questions/44105814/how-to-determine-the-current-operating-system-in-a-jenkins-pipeline