Ich habe eine groovige Datei, ich möchte aus dem Jenkinsfile laufen.
dh. load script.groovy
Ich bin mir jedoch nicht sicher, wie ich auf diese Datei verweisen kann, wenn sie im selben Verzeichnis wie das Jenkinsfile gespeichert ist. Ich lade die Jenkinsfile von git. Mir ist aufgefallen, dass ein Ordner mit dem Namen [email protected]
erstellt wird. Dies wird nicht im Arbeitsbereichsverzeichnis abgelegt. Ich könnte den Ordner hart codieren, aber ich bin mir nicht sicher, welche Regeln dazu gelten.
Java.io.FileNotFoundException: /opt/jenkins_home/jobs/my_job/workspace/script.groovy (No such file or directory)
Standardmäßig wird es aus dem Arbeitsbereich geladen, anstelle von [email protected]
.
Ich versuche, ein BuildFlow-Skript in ein Pipeline-Skript (Workflow) zu konvertieren. Aber ich finde, es ist nicht so einfach wie Kopieren und Einfügen.
Jenkinsfile
node {
//get parameters from Job
def builds = builds.tokenize(",")
def ip_address_node = ip_address_node.trim()
def port_node = port_node.trim()
def branch = branch.trim()
def workspace = pwd()
stage 'Checking out code from esb repository'
git branch: branch, url: 'ssh://[email protected]/integration_bus.git'
load '../[email protected]/esb_deploybar_pipeline/deploy_esb.groovy'
}
deploy_esb.groovy (Dies ist ein alter Buildflow, der versucht, in einer Pipeline auszuführen)
import groovy.transform.ToString
import groovy.transform.EqualsAndHashCode
@EqualsAndHashCode
@ToString
class BarDeploy {
String barFile
String app
String integrationServer
}
//parse csv
def csvItemsApps = new HashSet<BarDeploy>();
def csvItemsLibs = new HashSet<BarDeploy>();
def deploymentMapFile = new File(workspace + "/ESB_Deployment_Map.csv")
def isFirstLine = true
stage 'Parsing ESB Deployment CSV'
deploymentMapFile.withReader { reader ->
while(line = reader.readLine()) {
if(isFirstLine)
{
isFirstLine = false
continue
}
csvLine = line.split(",")
app = csvLine[0]
intServer = csvLine[1]
def barDeploy = new BarDeploy()
barDeploy.app = app
barDeploy.integrationServer = intServer
csvItemsApps.add(barDeploy)
//get shared libs
if(csvLine.length > 2 && csvLine[2] != null)
{
def sharedLibs = csvLine[2].split(";")
sharedLibs.each { libString ->
if(!libString.isAllWhitespace())
{
def lib = new BarDeploy()
lib.app = libString
lib.integrationServer = intServer
csvItemsLibs.add(lib)
}
};
}
}
};
//get list of bar files to deploy from html and consolidate bar files to deploy with apps in csv
for (int i = 0; i < builds.size(); i+=3)
{
if(builds[i].equals("false"))
{
//Don't deploy bar if checkbox isn't selected
continue
}
foundInCSV = false
appToDeploy = builds[i + 1]
barFileToDeploy = builds[i + 2]
iterator = csvItemsApps.iterator()
while (iterator.hasNext())
{
barDeploy = iterator.next()
if(appToDeploy.equalsIgnoreCase(barDeploy.app))
{
barDeploy.barFile = barFileToDeploy
foundInCSV = true
}
}
iterator = csvItemsLibs.iterator()
while (iterator.hasNext())
{
barDeploy = iterator.next()
if(appToDeploy.equalsIgnoreCase(barDeploy.app))
{
barDeploy.barFile = barFileToDeploy
foundInCSV = true
}
}
if(foundInCSV == false)
{
throw new RuntimeException("App: " + appToDeploy + " not found in ESB_Deployment_Map.csv. Please add CSV Entry.")
}
}
//Do deploy, deploy shared libs first
deployCSVItemsInParallel(ip_address_node,port_node,branch,env_key,csvItemsLibs)
deployCSVItemsInParallel(ip_address_node,port_node,branch,env_key,csvItemsApps)
def deploy(ip_address_node,port_node,branch,deployItem,env_key)
{
def integrationServer = deployItem.integrationServer
def app = deployItem.app
def barFile = deployItem.barFile
if(barFile == null)
{
return;
}
println("Triggering Build -> ESB App = " + app + ", Branch = "
+ branch + ", Barfile: " + barFile + ", Integration Server = " + integrationServer + ", IP Address: " + ip_address_node
+ ", Port: " + port_node + ", Env_Key: " + env_key)
build_closure = { ->
build("esb_deploybar",
ip_address_node: ip_address_node, port_node: port_node,
integrationServer: integrationServer, branch: branch, app: app, barFile: barFile, env_key: env_key)
}
return build_closure
}
def deployCSVItemsInParallel(ip_address_node,port_node,branch,env_key,csvItems)
{
def build_closures = []
iterator = csvItems.iterator()
while (iterator.hasNext())
{
barDeploy = iterator.next()
def build_closure = deploy(ip_address_node,port_node,branch,barDeploy,env_key)
if(build_closure != null)
{
build_closures.add(build_closure)
}
}
if(build_closures?.size() > 0)
{
parallel(build_closures)
}
}
Wenn die deploy_esb.groovy -Datei im selben SCM wie die Jenkins-Datei gespeichert ist, können Sie Folgendes tun:
node {
def workspace = pwd()
load "${workspace}@script/esb_deploybar_pipeline/deploy_esb.groovy"
}
Es gibt ein Szenario, von dem ich niemanden erwähnt habe. So laden Sie die Groovy-Skripte, wenn der Job auf einem Jenkins agent/slave ausgeführt werden soll, und nicht auf dem master .
Da der Master das Jenkins-Pipeline-Projekt von SCM auscheckt, befinden sich die Groovy-Skripts nur im Dateisystem des Masters . Also während dies funktioniert:
node {
def workspace = pwd()
def Bar = load "${workspace}@script/Bar.groovy"
Bar.doSomething()
}
Es ist nur ein glücklicher Zufall, weil der Knoten, der die Pipeline von SCM klont, derselbe ist, der versucht, die groovigen Skripte darin zu laden. Fügen Sie jedoch einfach den Namen eines anderen Agenten hinzu, der ausgeführt werden soll:
node("agent1"){
def workspace = pwd()
def Bar = load "${workspace}@script/Bar.groovy"
Bar.doSomething()
}
Wird fehlschlagen, was zu Folgendem führt:
Java.io.IOException: Java.io.FileNotFoundException: /Jenkins/workspace/[email protected]/Bar.groovy (No such file or directory)
Dies ist weil dieser Pfad:
/Jenkins/workspace/[email protected]/
Ist nur auf der Master-Jenkins-Box vorhanden. Nicht in der Box mit agent1 .
Wenn Sie also mit diesem Problem konfrontiert sind, laden Sie die groovigen Skripts vom Master in global deklarierte Variablen, damit der Agent sie verwenden kann:
def Bar
node {
def workspace = pwd()
if(isUnix()){
Bar = load "${workspace}@script/Bar.groovy"
}
else{
Bar = load("..\\[email protected]\\Bar.groovy")
}
}
node("agent1"){
Bar.doSomething()
}
Hinweis: Die Variable , die verwendet wird, um das Modul zwischen Knoten zu übergeben, muss außerhalb der Knoten Blöcke deklariert werden.
wenn sich diese script.groovy-Datei wie die Jenkins-Datei im Stamm Ihres Projekts befindet, wird sie von git in den gleichen Ordner wie Ihre Jenkins-Datei abgerufen. Der Befehl, den Sie verwenden, sollte also funktionieren.
Bekommst du einen Fehler? Bitte geben Sie in diesem Fall weitere Details an.
EDIT: Jetzt kann ich sehen, was in Ihrem Jenkinsfile ist. Ich sehe, dass Sie ein Git-Projekt namens integration_bus auschecken, in dem sich das groovige Skript befindet. Sie können den Ort angeben, an dem das ausgecheckt ist:
checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'esb_deploy']], submoduleCfg: [], userRemoteConfigs: [[url: 'ssh://[email protected]/integration_bus.git']]])
im Gegensatz zu dem, was Sie haben
git branch: branch, url: 'ssh://[email protected]/integration_bus.git'
Dann sollten Sie in der Lage sein, das groovige Skript im Ordner esb_deploy auf diese Weise zu referenzieren
load 'esb_deploy/esb_deploybar_pipeline/deploy_esb.groovy'
Hatte das gleiche Problem. Am Ende wurde eine zusätzliche Klonoperation ausgeführt, um eine Kopie des Skript-Repos unter Arbeitsbereich zu erhalten, damit ich zuverlässig auf groovige Dateien zugreifen kann:
dir ('SCRIPTS_DIR') {
checkout scm
commonScripts = load 'subdir/Common.groovy' // no def, so script is global
}
Sie können einfach davon ausgehen, dass alle Dateivorgänge in Jenkinsfile
relativ zum aktuellen Arbeitsbereich sind (der Standardarbeitsbereich, wenn Sie load
in einem node
verwenden).
Wenn sich also die Zieldatei (z. B. deploy_esb.groovy
) im Ordner foo
in Ihrem SCM befindet, sollte dies ohne zusätzliche Konfiguration funktionieren:
git branch: branch, url: 'ssh://[email protected]/integration_bus.git'
load 'foo/deploy_esb.groovy'
Oder wenn sich die zu ladende Datei im selben Repository befindet wie das Jenkinsfile
:
checkout scm
load 'foo/deploy_esb.groovy'
Das sollte funktionieren
load "${WORKSPACE}/../${JOB_NAME}@script/esb_deploy/esb_deploybar_pipeline/deploy_esb.groovy"