19

Mam plik groovy, chcę uruchomić z pliku Jenkinsfile.Jak mogę odwołać się do katalogu Jenkinsfile z Pipeline?

tj. load script.groovy

Jednak nie jestem pewien, w jaki sposób mogę odwołać się do tego pliku, jeśli jest on przechowywany w tym samym katalogu, co plik Jenkinsfile. Ładuję plik Jenkinsfile z git. Zauważyłem, że tworzy on folder o nazwie [email protected]. Nie umieszcza tego w katalogu obszaru roboczego. Mogę kodować folder, ale nie mam pewności co do zasad i wydaje mi się, że ponowne zbadanie kodu jest trochę zbędne.

java.io.FileNotFoundException: /opt/jenkins_home/jobs/my_job/workspace/script.groovy (No such file or directory) 

domyślnie ładuje od roboczego, zamiast [email protected]

Próbuję przekonwertować skrypt BuildFlow do rurociągu (Workflow) skryptu. Ale znajduję, to nie jest tak proste jak kopiowanie i wklejanie.

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 (to jest od starego buildflow, starając się uruchomić w rurociągu)

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) 
    } 
} 
+0

Proszę zaksięgować odpowiednią sekcję swojego pliku jenkinsfile –

+0

Dołączyłem cały używany kod źródłowy. – CodyK

Odpowiedz

1

jeśli ten plik script.groovy znajduje się w katalogu głównym projektu tak jak plik Jenkinsfile, zostanie pobrany z git do tego samego folderu, co plik Jenkinsfile. Polecenie, którego używasz, powinno działać poprawnie.

Czy otrzymujesz błąd? Podaj więcej szczegółów, jeśli tak.

EDYCJA: Teraz mogę zobaczyć, co jest w twoim Jenkinsfile, widzę, że sprawdzasz projekt git o nazwie integration_bus, gdzie znajduje się ten groovy skrypt. Można określić miejsce, w którym to jest wyrejestrowany tak:

checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'esb_deploy']], submoduleCfg: [], userRemoteConfigs: [[url: 'ssh://[email protected]/integration_bus.git']]]) 

w przeciwieństwie do tego, co masz

git branch: branch, url: 'ssh://[email protected]/integration_bus.git' 

Następnie powinieneś być w stanie odwołać Groovy skryptu w folderze esb_deploy tak

load 'esb_deploy/esb_deploybar_pipeline/deploy_esb.groovy' 
+0

Skrypt ładuje się z katalogu obszaru roboczego, zamiast skryptu workspace @, co nie jest wielką sprawą, ale raczej nie utrudnia kodowania tej ścieżki. – CodyK

+0

Plik groovy jest rzeczywiście zlokalizowany w innym repozytorium. Znajduje się w tym samym repozytorium co Jenkinsfile. Mam go do pracy, odwołując się do pliku takiego jak ten ładunek "../[email protected]/esb_deploybar_pipeline/deploy_esb.groovy". Mam inne problemy, ale to są inne problemy. Dzięki – CodyK

+0

To wciąż wydaje się nieco hacky, prawda? Co powiesz na dodanie swojego groovy skryptu pomocniczego do repozytorium git, które następnie dodajesz do odpowiednich projektów jako submoduł? – sebkraemer

0

można po prostu założyć, że wszystkie operacje na plikach w Jenkinsfile są w stosunku do bieżącego obszaru roboczego (który jest domyślny obszar roboczy podczas korzystania load wewnątrz node).

Więc jeśli plik docelowy (słownie deploy_esb.groovy) znajduje się wewnątrz folderu foo w SCM, to powinno działać bez dodatkowej konfiguracji:

git branch: branch, url: 'ssh://[email protected]/integration_bus.git' 
load 'foo/deploy_esb.groovy' 

albo to, czy plik do załadowania jest w tym samym repozytorium niż z Jenkinsfile:

checkout scm 
load 'foo/deploy_esb.groovy' 
+0

Problem polegał na tym, że plik groovy znajduje się w tym samym repozytorium co plik Jnkins. Zignoruj ​​ten klon git, który nie jest od niego oddzielony. Właśnie dodałem, gdy kopiowałem i wklejałem plik Jenkinsa. Ale ładuję plik Jennkins z SCM, więc tworzy katalog skryptu workspace @. Właśnie użyłem tego: '../[email protected]/deploy_esb.groovy' t załaduj skrypt – CodyK

+0

Następnie użyj: 'checkout scm', a następnie krok' load'. – amuniz

+2

Wiem, to było trochę zbyteczne, aby sprawdzić kod dwa razy. – CodyK

9

Jeśli deploy_esb.groovy plik jest przechowywany w tym samym SCM jako Jenkinsfile można zrobić:

node {  
    def workspace = pwd() 
    load "${workspace}@script/esb_deploybar_pipeline/deploy_esb.groovy" 
} 
+3

Nie powiedzie się, jeśli zadanie może zostać wykonane równolegle, ponieważ Jenkins utworzy obszary robocze takie jak 'nazwa_użytkownika @ 2' i' nazwa_użytkownika @ 3', ale ponownie użyje 'nazwa_programu @ skrypt'. – kadrach

7

Jest jeden scenariusz, którego nie widziałem, aby ktokolwiek wspomniał.W jaki sposób załadować skrypty Groovy, gdy zadanie ma zostać uruchomione na Jenkins agent/niewolnik, a nie na master.

Ponieważ master jest tym, który sprawdza projekt potoku Jenkinsa z SCM, , skrypty Groovy można znaleźć tylko w systemie plików master. Tak więc, to będzie działać:

node {  
    def workspace = pwd() 
    def Bar = load "${workspace}@script/Bar.groovy" 
    Bar.doSomething() 
} 

To tylko szczęśliwy zbieg okoliczności, ponieważ węzeł, który klonuje rurociągu z SCM jest ten sam, który próbuje załadować groovy skrypty w nim. Jednak wystarczy dodać nazwę inny środek, aby wykonać na:

node("agent1"){ 
    def workspace = pwd() 
    def Bar = load "${workspace}@script/Bar.groovy" 
    Bar.doSomething() 
} 

Czy uda, powodując:

java.io.IOException: java.io.FileNotFoundException: /Jenkins/workspace/[email protected]/Bar.groovy (No such file or directory) 

To dlatego tą drogą:

/Jenkins/workspace/[email protected]/ 

istnieje tylko na główne pudełko Jenkinsa. Nie w pudełku działającym pod numerem agent1.

Więc jeśli w obliczu tego problemu, upewnij się, aby załadować odjechane skrypty z mastera do globalnie zadeklarowane zmienne, więc agent może następnie wykorzystać je:

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() 
} 

Uwaga: Zmienna używany do przekazywania modułu między węzłami musi być zadeklarowany jako poza blokami węzła.

+1

Jednym z nich jest tutaj, jeśli liczba executorów na węźle głównym jest ustawiona na zero. W takim przypadku wydaje się, że 'load' nie ma możliwości znalezienia twojego groovy pliku. –

+0

Masz rację @HaroldPutman. W takim przypadku jedynym sposobem, jaki widzę naprzód, byłoby użycie kroku git do sklonowania repozytorium dla skryptów (Jenkinsfile i Groovy) jeszcze raz z bloku węzła ("agent1").Szkoda, że ​​trzeba sklonować skrypty dwa razy (od mistrza, a następnie od agenta), ale byłbyś do tego zmuszony przez środowisko, w którym żaden wykonawca nie byłby dozwolony na mistrza. – Mig82

Powiązane problemy