我试图在我们的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 (没有此类文件或目录)位于java.io.FileInputStream.open0(本机 方法)在java.io.FileInputStream.open(FileInputStream.java:195) java.io.FileInputStream。(FileInputStream.java:138)在 groovy.util.CharsetToolkit。(CharsetToolkit.java:71)在 org.codehaus.groovy.runtime.ResourceGroovyMethods.newReader(ResourceGroovyMethods.java:1572) 在 org.codehaus.groovy.runtime.ResourceGroovyMethods.readLines(ResourceGroovyMethods.java:533) 在 org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.asCollection(DefaultTypeTransformation.java:461) 在 org.codehaus.groovy.runtime.DefaultGroovyMethods.iterator(DefaultGroovyMethods.java:15955) 在org.codehaus.groovy.runtime.dgm $ 367.doMethodInvoke(来源不明) 在groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213) 在groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022) 在 org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:913) 在 org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:904) 在 org.codehaus.groovy.runtime.InvokerHelper.asIterator(InvokerHelper.java:573) 在org.codehaus.groovy.runtime.InvokerHelper $ asIterator.call(未知 来源) org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) 在 org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) 在 com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20) 在 com.cloudbees.groovy.cps.CpsDefaultGroovyMethods.each(CpsDefaultGroovyMethods:1890) 在WorkflowScript.run(WorkflowScript:8)在 cps.transform (本机方法),位于com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57) 在 com.cloudbees.groovy.cps.impl.FunctionCallBlock $ ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109) 在 com.cloudbees.groovy.cps.impl.FunctionCallBlock $ ContinuationImpl.fixArg(FunctionCallBlock.java:82) 在sun.reflect.GeneratedMethodAccessor324.invoke(未知来源)在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:498)在 com.cloudbees.groovy.cps.impl.ContinuationPtr $ ContinuationImpl.receive(ContinuationPtr.java:72) 在 com.cloudbees.groovy.cps.impl.LocalVariableBlock $ LocalVariable.get(LocalVariableBlock.java:39) 在 com.cloudbees.groovy.cps.LValueBlock $ GetAdapter.receive(LValueBlock.java:30) 在 com.cloudbees.groovy.cps.impl.LocalVariableBlock.evalLValue(LocalVariableBlock.java:28) 在 com.cloudbees.groovy.cps.LValueBlock $ BlockImpl.eval(LValueBlock.java:55) 在com.cloudbees.groovy.cps.LValueBlock.eval(LValueBlock.java:16)处 com.cloudbees.groovy.cps.Next.step(Next.java:83)在 com.cloudbees.groovy.cps.Continuable $ 1.call(Continuable.java:174)在 com.cloudbees.groovy.cps.Continuable $ 1.call(Continuable.java:163)在 org.codehaus.groovy.runtime.GroovyCategorySupport $ ThreadCategoryInfo.use(GroovyCategorySupport.java:129) 在 org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:268) 在com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163) 在 org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:182) 在 org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332) 在 org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access $ 200(CpsThreadGroup.java:83) 在 org.jenkinsci.plugins.workflow.cps.CpsThreadGroup $ 2.call(CpsThreadGroup.java:244) 在 org.jenkinsci.plugins.workflow.cps.CpsThreadGroup $ 2.call(CpsThreadGroup.java:232) 在 org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService $ 2.call(CpsVmExecutorService.java:64) 在java.util.concurrent.FutureTask.run(FutureTask.java:266)在 hudson.remoting.SingleLaneExecutorService $ 1.run(SingleLaneExecutorService.java:131) 在 jenkins.util.ContextResettingExecutorService $ 1.run(ContextResettingExecutorService.java:28) 在 jenkins.security.ImpersonatingExecutorService $ 1.run(ImpersonatingExecutorService.java:59) 在 java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511) 在java.util.concurrent.FutureTask.run(FutureTask.java:266)在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 在 java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:624) 在java.lang.Thread.run(Thread.java:748)上完成:失败
sh“ cat $ env.SERVICE_VERSIONS_FILE”返回正确的结果(即,它会打印文件的内容) 在主服务器上执行时,管道可以正常工作。感觉我可能会缺少一些灾难性的简单事情?还是一个错误?
答案 0 :(得分:0)
确认service_versions.csv在源代码管理中,并且首先被检出到Jenkins工作区。
Jenkins中的主从机制以及将作业绑定到从属的操作应确保将工作空间复制到从属。您应该在文件系统上该位置下看到一个工作区,以配置从站存储文件。您应该可以在“管理Jenkins”>“管理节点”页面上找到它,然后查看节点的属性。
如果您的文件属于.NET解决方案的一部分,并且文件属性未设置为“复制始终”,则您还会看到此类问题。
根据您的评论进行更新:
您的猫行在env前面包含一个'$'字符,但下一行则没有:
new File(env.SERVICE_VERSIONS_FILE).each { line ->
好像您在此行的env前面缺少一个“ $”,它应该是:
new File(${env.SERVICE_VERSIONS_FILE}).each { line ->
答案 1 :(得分:0)
我不太确定它的工作方式或原因,但我找到了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 ->
到
readFile(env.SERVICE_VERSIONS_FILE).split("\n").each { line ->
它有效。
答案 2 :(得分:0)
我通过提供Jenkinsfile的自定义路径解决了该错误。