Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/jenkins/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jenkins 如何在声明性管道中等待用户输入而不阻塞重量级执行器_Jenkins_Jenkins Pipeline - Fatal编程技术网

Jenkins 如何在声明性管道中等待用户输入而不阻塞重量级执行器

Jenkins 如何在声明性管道中等待用户输入而不阻塞重量级执行器,jenkins,jenkins-pipeline,Jenkins,Jenkins Pipeline,我正在将现有的构建管道重建为jenkins声明性管道(多分支管道),在处理构建传播时遇到问题 打包和存放所有相关文件后,管道应该等待用户输入以触发部署 如果我只是添加一个输入步骤,那么当前构建节点将被阻止。由于这个执行器相当重,我想把这一步移到一个更轻的机器上 最初,我作为一个脚本化管道来完成这项工作,只创建了两个不同的节点('label')块。我有没有办法用声明性语法做类似的事情 node('spine') { stage('builder') { sh 'mvn c

我正在将现有的构建管道重建为jenkins声明性管道(多分支管道),在处理构建传播时遇到问题

打包和存放所有相关文件后,管道应该等待用户输入以触发部署

如果我只是添加一个输入步骤,那么当前构建节点将被阻止。由于这个执行器相当重,我想把这一步移到一个更轻的机器上

最初,我作为一个脚本化管道来完成这项工作,只创建了两个不同的
节点('label')
块。我有没有办法用声明性语法做类似的事情

node('spine') { 
    stage('builder') {
        sh 'mvn clean compile'
        stash name: 'artifact', includes: 'target/*.war'
    }
}
node('lightweight') {
    stage('wait') {
        timeout(time:5, unit:'DAYS') {
            input message:'Approve deployment?'
        }
    }
    // add deployment stages
}
我已经试过几件事了:

在顶层配置代理并向传播步骤添加额外的代理配置,但是由于顶层定义的构建节点没有停止,我有两个执行器阻塞

在顶层设置
agent none
,并配置每个步骤的代理。那么git签出在第一个节点上不存在

编辑1

我按照您的建议重新配置了管道,目前看起来如下:

pipeline {
agent none
tools {
    maven 'M3'
}
stages {
    stage('Build') {
        agent { label 'spine' }
        steps {
            checkout scm // needed, otherwise the workspace on the first step is empty
            sh "mvn clean compile"
        }
    }
    stage('Test') {
        agent { label 'spine' }
        steps {
            sh "mvn verify" // fails because the workspace is empty aggain
            junit '**/target/surefire-reports/TEST-*.xml'
        }
    }
}
}
此生成将失败,因为工作区不会在步骤之间继续,因为它们不会在同一执行器上运行

编辑2

显然,有时步骤在同一个执行者身上运行,有时不运行。(我们根据需要在mesos/dcos集群上生成构建从属,因此在构建中期更改executor将是一个问题)

我希望jenkins只使用当前执行器运行,只要代理定义中的标签不变。

请参阅:不要:在节点块中使用输入。在声明性管道中,节点选择通过
agent
指令完成

本文档描述了如何为管线定义
none
,然后使用阶段级别
agent
指令在所需节点上运行阶段。我也尝试了相反的方法(在某个节点上定义一个全局代理,然后在阶段级别为输入定义
none
),但这不起作用。如果管道分配了从属设备,则无法为一个或多个特定阶段释放从属设备

这是以下结构:


通常,构建阶段在标记为“yona”的构建从站上执行,但输入阶段在主站上运行。

在顶部使用“无代理”,并为每个阶段定义代理,包括输入步骤的阶段除外

资料来源:讨论


更新:您所说的“git签出在第一个节点上不存在”是什么意思?请展示到目前为止您对声明性管道的了解。

另一种方法是使用expression指令和beforeAgent,它跳过了“decision”步骤,避免了与“env”全局变量的混淆:


我知道这个线程很旧,但我相信除了隐藏之外,解决“编辑2”问题的一个方法是使用嵌套的阶段

根据本页:

。。。如果您正在管道中使用多个代理,但希望确保使用同一代理的阶段使用相同的工作区,则可以使用带有代理指令的父阶段,然后其stages指令中的所有阶段将在同一工作区中的同一执行器上运行

以下是提供的示例:

pipeline {
    agent none

    stages {
        stage("build and test the project") {
            agent {
                docker "our-build-tools-image"
            }
            stages {
               stage("build") {
                   steps {
                       sh "./build.sh"
                   }
               }
               stage("test") {
                   steps {
                       sh "./test.sh"
                   }
               }
            }
            post {
                success {
                    stash name: "artifacts", includes: "artifacts/**/*"
                }
            }
        }

        stage("deploy the artifacts if a user confirms") {
            input {
                message "Should we deploy the project?"
            }
            agent {
                docker "our-deploy-tools-image"
            }
            steps {
                sh "./deploy.sh"
            }
        }
    }
}

OP的问题是如何“在声明性管道中等待用户输入而不阻塞…”。这似乎不可能。尝试使用代理:无不会释放声明性管道中的生成执行器

这:

。。。运行时,如下所示:

pipeline {
agent none
tools {
    maven 'M3'
}
stages {
    stage('Build') {
        agent { label 'spine' }
        steps {
            checkout scm // needed, otherwise the workspace on the first step is empty
            sh "mvn clean compile"
        }
    }
    stage('Test') {
        agent { label 'spine' }
        steps {
            sh "mvn verify" // fails because the workspace is empty aggain
            junit '**/target/surefire-reports/TEST-*.xml'
        }
    }
}
}

。。。这是:


这不适用于声明性管道,没有节点块。我尝试了与您相同的方法,但遇到了问题。显然,即使工作区在同一个代理上运行,它也不会从一个阶段转移到另一个阶段。我的第二个构建步骤(maven builds)发现一个空工作空间,因此这相当于此脚本化管道:。这是14行代码而不是29行。。。难道声明性管道不应该更简单吗?在分布式管道中使用管道,您需要将所需的工件从一个阶段存放到另一个阶段。您还可以签出SCM repo,如果它保存了您需要的文件。Jenkins 2允许管道在任何时候在任何代理上运行,并提供了隐藏机制让您可以四处移动。Stash也有助于在后台运行时,如果主控器关闭,那么Stash可以在主控器返回并且管道恢复时继续上下文。回答得好,谢谢!但是最佳实践呢。不允许:使用env全局变量设置环境变量?我更喜欢将输入结果分配给groovy变量,该变量也可以稍后在管道中使用。这是迄今为止最好的答案。OP的问题是“如何在声明性管道中等待用户输入而不阻塞重量级执行器”,他可以阻塞轻量级执行器。嘿,Johnton!通过将beforeAgent选项与表达式块相结合,可以避免阻塞代理。有关更多详细信息,请查看我的答案。顺便说一句,我们想念你,希望一切顺利!这很有帮助。我能够把这个答案和埃梅里诺的答案结合起来,得到我想要的。
pipeline {
    agent none

    stages {
        stage("build and test the project") {
            agent {
                docker "our-build-tools-image"
            }
            stages {
               stage("build") {
                   steps {
                       sh "./build.sh"
                   }
               }
               stage("test") {
                   steps {
                       sh "./test.sh"
                   }
               }
            }
            post {
                success {
                    stash name: "artifacts", includes: "artifacts/**/*"
                }
            }
        }

        stage("deploy the artifacts if a user confirms") {
            input {
                message "Should we deploy the project?"
            }
            agent {
                docker "our-deploy-tools-image"
            }
            steps {
                sh "./deploy.sh"
            }
        }
    }
}
pipeline {
agent none
stages {
    stage('Build') {
        agent { label 'big-boi' }
        steps {
            echo 'Stubbed'
        }
    }

    stage('Prompt for deploy') {
        agent { label 'tiny' }
        steps {
            input 'Deploy this?'
        }
    }

    stage('Deploy') {
        agent { label 'big-boi' }
        steps {
            echo "Deploying"
            build job: 'deploy-to-higher-environment'
        }
    }
}
}