詹金斯 - 多分支管道无法解释的故障



在我的管道中,我使用管道实用程序步骤插件的readJSON和writeJSON方法来读取/写入管道阶段的文件。对于正常的管道,一切都很好。但是,当我创建"多分支管道"时,同一管道失败。当后续阶段尝试使用 readJSON 读取本应由前一阶段生成的文件时,就会发生故障。奇怪的部分是:在一个阶段内,生成的文件可供命令使用(命令aws ecs register-task-definition成功(,之后在工作区/var/jenkins_home/workspace/TestPipeline节点上不存在。

为了关注失败,我只粘贴管道的相关阶段。

stage('RegisterTaskDefinition') {
agent any
steps {
sh 'printenv'
script {            
def templateFile = env.TEMPLATE_BASE_PATH +'/' + TASK_DEF_TEMPLATE
def taskDefinitionTemplate = readJSON(file: templateFile)
taskDefinitionTemplate.taskRoleArn = env.TASK_ROLE_ARN
taskDefinitionTemplate.executionRoleArn = env.EXECUTION_ROLE_ARN
taskDefinitionTemplate.containerDefinitions[0].image = "NewImage"
taskDefinitionTemplate.containerDefinitions[0].portMappings[0].containerPort = env.APP_PORT.toInteger()
taskDefFile = env.TEMPLATE_BASE_PATH + '/' + env.TASK_DEFINITION_FILE
writeJSON(file: taskDefFile, json: taskDefinitionTemplate)
def registerTaskDefinitionOutput = sh (
script: "aws ecs register-task-definition --cli-input-json file://${taskDefFile}",
returnStdout: true
).trim()
echo "Register Task Def result: ${registerTaskDefinitionOutput}"
def registerTaskDefOutputFile = env.TEMPLATE_BASE_PATH + '/registerTaskDefOutput.json'
echo "********************************"
sh 'pwd'
writeJSON(file: registerTaskDefOutputFile, json: registerTaskDefinitionOutput, pretty: 2)
echo "********************************${registerTaskDefOutputFile}"
}
}
}
stage('CreateTaskSet') {
agent any
steps{
script{
def registerTaskDefOutputFile = env.TEMPLATE_BASE_PATH + '/' + env.REGISTER_TASK_DEF_OUTPUT
def taskSetTemplateFile = env.TEMPLATE_BASE_PATH + '/' + env.TASK_SET_TEMPLATE_FILE
def taskSetFile = env.TEMPLATE_BASE_PATH + '/' + env.TASK_SET_FILE
def registerTaskDefinitionOutput = readJSON(file: registerTaskDefOutputFile)
def taskSetTemplateJson = readJSON(file: taskSetTemplateFile)
taskSetTemplateJson.taskDefinition = registerTaskDefinitionOutput.taskDefinition.taskDefinitionArn
taskSetTemplateJson.loadBalancers[0].containerPort = env.APP_PORT.toInteger()
taskSetTemplateJson.loadBalancers[0].targetGroupArn = targetGroupArn
writeJSON(file: taskSetFile, json: taskSetTemplateJson, pretty: 2)
}
}
}

澄清一下,RegisterTaskDefinition阶段成功,失败发生在CreateTaskSet阶段。

生成的异常是:

java.io.FileNotFoundException: /var/jenkins_home/workspace/TestPipeline/infrastructure/registerTaskDefOutput.json does not exist.
at org.jenkinsci.plugins.pipeline.utility.steps.json.ReadJSONStepExecution.doRun(ReadJSONStepExecution.java:82)
at org.jenkinsci.plugins.pipeline.utility.steps.AbstractFileOrTextStepExecution.run(AbstractFileOrTextStepExecution.java:32)
at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution.lambda$start$0(SynchronousNonBlockingStepExecution.java:47)
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)

我有以下问题:

  1. 如何解释两种管道类型的行为差异?
  2. 对于普通管道,我可以在节点上的/var/jenkins_home/workspace/TestPipeline下看到管道生成的文件。对于"多分支管道",情况并非如此。Jenkins 使用什么目录来表示"多分支管道"?
  3. 哪些日志可以帮助我诊断问题?

我找不到任何文档来解释两种管道类型的行为差异。我将不胜感激任何建议。

从你的代码:

stage('RegisterTaskDefinition') {
agent any

stage('CreateTaskSet') {
agent any

这两个阶段完全有可能在不同的代理上运行,因为您已经告诉 Jenkins,您希望一个随机代理运行第一阶段,一个随机代理运行第二阶段。这些代理以前可能是相同的;但是,没有要求它们会相同。

为防止这种情况,请尽早分配节点,不要更改它:

pipeline {
agent any
stage('1') { ... }
stage('2') { ... }
}

这保证了两个阶段将在同一代理上运行,因此第一阶段写入${env.WORKSPACE}的结果将可用于第二个代理。

最新更新