Файл не найден в скрипте конвейера Jenkins

Я пытаюсь запустить сценарий конвейера, запущенный в настоящее время на нашем главном узле Jenkins, на удаленном узле Jenkins. Но я получаю странное FileNotFound исключение.

Самая простая версия конвейера, с которой мне удалось воспроизвести проблему, такова:

node("remoteNode") {
env.SERVICE_VERSIONS_FILE = pwd() + '/service_versions.csv'
stage('Read file') {
  git credentialsId: '***', url: '***'      
  sh "cat $env.SERVICE_VERSIONS_FILE"
  new File(env.SERVICE_VERSIONS_FILE).each { line ->
    echo "$line"
   }
  }
}

Что приводит к:

>java.io.FileNotFoundException: /home/***/workspace/DeploymentPipelines/test-deployer/service_versions.csv
> (No such file or directory)   at java.io.FileInputStream.open0(Native
> Method)   at java.io.FileInputStream.open(FileInputStream.java:195)   at
> java.io.FileInputStream.<init>(FileInputStream.java:138)  at
> groovy.util.CharsetToolkit.<init>(CharsetToolkit.java:71)     at
> org.codehaus.groovy.runtime.ResourceGroovyMethods.newReader(ResourceGroovyMethods.java:1572)
>   at
> org.codehaus.groovy.runtime.ResourceGroovyMethods.readLines(ResourceGroovyMethods.java:533)
>   at
> org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.asCollection(DefaultTypeTransformation.java:461)
>   at
> org.codehaus.groovy.runtime.DefaultGroovyMethods.iterator(DefaultGroovyMethods.java:15955)
>   at org.codehaus.groovy.runtime.dgm$367.doMethodInvoke(Unknown Source)
>   at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
>   at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
>   at
> org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:913)
>   at
> org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:904)
>   at
> org.codehaus.groovy.runtime.InvokerHelper.asIterator(InvokerHelper.java:573)
>   at org.codehaus.groovy.runtime.InvokerHelper$asIterator.call(Unknown
> Source)   at
> org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
>   at
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
>   at
> com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
>   at
> com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:1890)
>   at WorkflowScript.run(WorkflowScript:8)     at
> ___cps.transform___(Native Method)    at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
>   at
> com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
>   at
> com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
>   at sun.reflect.GeneratedMethodAccessor324.invoke(Unknown Source)    at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>   at java.lang.reflect.Method.invoke(Method.java:498)     at
> com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
>   at
> com.cloudbees.groovy.cps.impl.LocalVariableBlock$LocalVariable.get(LocalVariableBlock.java:39)
>   at
> com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
>   at
> com.cloudbees.groovy.cps.impl.LocalVariableBlock.evalLValue(LocalVariableBlock.java:28)
>   at
> com.cloudbees.groovy.cps.LValueBlock$BlockImpl.eval(LValueBlock.java:55)
>   at com.cloudbees.groovy.cps.LValueBlock.eval(LValueBlock.java:16)   at
> com.cloudbees.groovy.cps.Next.step(Next.java:83)  at
> com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)     at
> com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)     at
> org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:129)
>   at
> org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268)
>   at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
>   at
> org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:182)
>   at
> org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
>   at
> org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
>   at
> org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
>   at
> org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
>   at
> org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
>   at java.util.concurrent.FutureTask.run(FutureTask.java:266)     at
> hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
>   at
> jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
>   at
> jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
>   at
> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
>   at java.util.concurrent.FutureTask.run(FutureTask.java:266)     at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
>   at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
>   at java.lang.Thread.run(Thread.java:748)   Finished: FAILURE

sh "cat $env.SERVICE_VERSIONS_FILE" возвращает правильные результаты (т. Е. Распечатывает содержимое файла).

Конвейер отлично работает, когда выполняется на мастере. Такое чувство, что я могу упустить что-то катастрофически простое? Или это ошибка?


person vruum    schedule 10.10.2018    source источник


Ответы (3)


Я не совсем уверен, как и почему это работает, но я нашел это https://stackoverflow.com/a/38679858/985291 и удалось решить проблему с помощью шага readFile https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#readfile-read-file-from-workspace.

так в основном, изменение

 new File(env.SERVICE_VERSIONS_FILE).each { line ->

to

 readFile(env.SERVICE_VERSIONS_FILE).split("\n").each { line ->

и это работает.

РЕДАКТИРОВАТЬ. Как отмечает @ zett42 в своем комментарии, это, по-видимому, задумано, и вы должны просто использовать шаги сборки (readFile, writeFile) при работе с файлами. (https://issues.jenkins-ci.org/browse/JENKINS-37577?focusedCommentId=267445&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-267445 )

person vruum    schedule 11.10.2018
comment
Основная причина объясняется на комментарий к этой проблеме Jira: Поведение такое, как задумано. Команды Java низкого уровня всегда будут обращаться к файлам на главном сервере. Существуют команды конвейера, такие как readFile () и writeFile (), которые позволяют получить доступ к файлам в рабочих областях узлов. - person zett42; 24.02.2020
comment
привет @ zett42, спасибо, я думаю, ты прав, это все объясняет. Не стесняйтесь размещать свой комментарий в качестве ответа, и я его приму, в противном случае я обновлю свой ответ, чтобы сослаться на ваш комментарий. - person vruum; 25.02.2020
comment
Я не думаю, что нам нужен другой ответ, в этом ответе есть вся необходимая сейчас информация. Ваше здоровье! - person zett42; 25.02.2020

Убедитесь, что service_versions.csv находится в системе управления версиями и сначала извлекается в рабочую область Jenkins.

Механизм «главный-подчиненный» в Jenkins и действие привязки задания к подчиненному должны гарантировать, что рабочее пространство скопировано на подчиненное устройство. Вы должны увидеть рабочее пространство в файловой системе под местоположением, которое нужно настроить для ведомого устройства для хранения файлов. Вы должны найти это на странице «Управление Jenkins»> «Управление узлами», а затем просмотрите свойства своего узла.

Если ваш файл является частью решения .NET, а для его свойств не задано значение «Всегда копировать», вы также можете увидеть подобные проблемы.

Обновление на основе вашего комментария:

Ваша строка cat включает символ '$' перед env, но в следующей строке его нет:

new File(env.SERVICE_VERSIONS_FILE).each { line ->

Похоже, вам не хватает символа '$' перед env в этой строке, и это должно быть:

new File(${env.SERVICE_VERSIONS_FILE}).each { line ->
person Andrew Gray    schedule 11.10.2018
comment
Я проверил, а файл есть. Вот почему я включил в конвейер команду sh cat ... Чтобы убедиться, что файл существует, прежде чем пытаться его прочитать. - person vruum; 11.10.2018

Я решил эту ошибку, указав собственный путь к моему файлу Jenkins.

person Ajay    schedule 01.06.2019