一、概述

Jenkins 任务有一个很重要的特性,那就是可以根据用户输入改变它们的行为。

DSL的input 骤就是让我们通过流水线获得用户输入的方法。

在脚本式流水线中 ,这个步骤接受与普通 Jenkins 务相同的参数类型。在声明式流水线中,有一个特殊的parameters指令,可以支持那些参数的子集。

二、输入

顾名思义, input 步骤允许你的流水线停下来等待用户响应

示例

stage("input") {
    input 'Continue to next stage?'
}

运行流水线后会出现一个带虚线的蓝色框
在这里插入图片描述
将鼠标放到蓝色虚框上,会弹出一个表单式的选择框,默认打印一条消息和提供给用户一个选择,即继续进行( Proceed )或者中止(Abort)。如下图所示
在这里插入图片描述
在控制台输出中,是一个包含链接的输出,可以通过点击这个链接继续或者停止
在这里插入图片描述
在这里插入图片描述
选择继续进行(Proceed )允许流水线继续运行。
选择中止(Abort )会造成流水线停止,并且该阶段状态被设置为中止的(aborted )。
在这里插入图片描述
注意:当系统执行了 input 步骤时,相应节点上的进程会被暂停。

input自身参数

消息( message)

显示给用户的消息,正如前面示例所演示的那样。消息也可以为空,表示为 input"。

自定义 ID (id)

一个ID 可以用来标示你的 input 步骤,便于一些自动化或者外部的处理。比如,在你希望通过 REST API 调用来响应的时候。

你可以在 input 步骤定义中添加 一个自定义的ID,如input_id

input id: 'input_id' , message: 'Continue to the next stage?'

那么POST URL请求格式为:

http://jenkins_url/job/[job_name]/[build_id]/input/input_id/proceedEmpty	#没有任何输入继续运行
http://jenkins_url/job/[job_name]/[build_id]/input/input_id/abort			#中止运行

如果Jenkins开启了CSRF,则需要先获取CSRF token,然后执行如下命令
curl命令获取Jenkins CSRF token

curl -- user <userid>:<password or token> -H "$CSRF_TOKEN" -X POST \
-s http://jenkins_url/job/[job_name]/[build_id]/input/input_id/proceedEmpty

OK 按钮字幕( ok)

可以使用不同的标签取代“Proceed ”。例如

input id: 'input_test' , message: 'Continue to the next stage?', ok: 'Yes'

在这里插入图片描述

允许的提交者(submitter)

逗号分隔的用户 ID 或组名列表,用于授权哪些人可以给予 响应。例如:

input id: 'input_test' , message: 'Continue to the next stage?', submitter: 'userl,user2'

存储批准提交者的参数( submitterParameter)

在这里插入图片描述

parameters(传统的Jenkin 参数类型)

在下面进行介绍

三、参数

使用input 语句,你可以选择添加任何一个标准的 Jenkins 参数类型

布尔型( boolean)

这是基本的 true/false 参数。

def inputResp = input id: "input_test",
                    message: "'Continue to the next stage?'",
                    parameters: [booleanParam(defaultValue: true, description: '这是个布尔类型', name: 'action')]

在这里插入图片描述

选项型( choice)

允许用户从一个选项列表中选择,列表中的第 一个值会作为默认值。

def inputResp = input id: "input_test",
                    message: "'Continue to the next stage?'",
                    parameters: [choice(choices:['mysql','oracle'], description: '这是选项型', name: 'action')]

在这里插入图片描述

凭证(credential)

允许用户选择一个类型并且设置凭证
可选择的凭证类型包括用户名和密码、 Docker 主机证书验证、 SSH 用户名及私钥,机密文件、机密文本及证书

def inputResp = input id: "input_test",
                    message: "'Continue to the next stage?'",
                    parameters: [credentials(credentialType: 'com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl', defaultValue: '', description: '请选择凭据', name: 'User And Pass', required: true)]

在这里插入图片描述
在这里插入图片描述

文件(file)

允许用户选择一个文件给流水线使用

文件会上传到工作空间下的test目录下,并命名为t1.txt

def inputResp = input id: "input_test",
                    message: "'Continue to the next stage?'",
                    parameters: [file(description: '上传文件', name: 'test/t1.txt')]

在这里插入图片描述

密码( password)

允许用户输入一个密码。对于密码文本,用户键人的时候会被隐藏起来。

def inputResp = input id: "input_test",
                    message: "'Continue to the next stage?'",
                    parameters: [password(defaultValue: '', description: 'Enter your password', name: 'passwd')]

在这里插入图片描述

运行( run)

允许用户从一个任务中选择一个特定的运行(已经执行过的构建 )
默认的运行是最新一次的运行。

def inputResp = input id: "input_test",
                    message: "'Continue to the next stage?'",
                    parameters: [run(description: 'Choose a run of the project', filter: 'SUCCESSFUL', name: 'RUN', projectName: 'aqx_pipeline')]
      println inputResp

在这里插入图片描述
在这里插入图片描述

字符串( string)

在这里插入图片描述

四、多个输入参数的返回值

上面 展示的所有示例, 只包含了单个参数,提供了一个简单的返回值,直接包含了用户的输入。
如果没有参数 ,返回值是null;如果有多个参数,将会返 一个映射( map), 你可以通过参数的名称抽取每一 参数的返回值。

def inputResp = input id: "input_test",
                    message: "'Continue to the next stage?'",
                    parameters: [string(defaultValue: '', description: '用户名', name: 'username', trim: true),
                                 password(defaultValue: '', description: '密码', name: 'passwd')]
println inputResp["username"]
println inputResp["passwd"]

在这里插入图片描述
在这里插入图片描述

五、实战

1、设置人工干预,决定是否部署到生产环境

脚本

#!groovy

stage("确认部署到生产"){
    def inputResp = input id: "input_${BUILD_NUMBER}", message: '''确认部署到生产请输入:approve''', parameters: [string(defaultValue: '', description: '''确认是否部署到生产,输入指令后点击Proceed,终止请点击Abort''', name: 'action')]
    
    if(inputResp != "approve")
    {
        throw new Exception("The input is incorrect, we abort this job..")
    }
    println "开始部署到生产......"
}

执行效果

在这里插入图片描述

2、设置人工干预,定义执行动作(可从失败的stage执行)

传入stagesRun的参数确定的情况

脚本
#!groovy

def ansible_path = "/etc/ansible/ansible_playbooks"
timestamps{    
    try {
        node(){
        	stage("配置安装参数"){
                echo "配置安装参数"
            }
            stage("安装docker"){
                stagesRun("installDocker",ansible_path)
            }        
        }//node
    }//try
    catch(Exception err){
        throw new Exception("*******Caught an exception: ${err}")
    }//catch
}

//install docker
def installDocker(ansible_path){
    dir(ansible_path){
        ansiblePlaybook become: true, 
        becomeUser: 'root',				//相当于sudo
        disableHostKeyChecking: true, 
        inventory: '/etc/ansible/hosts', 
        playbook: 'install_docker.yml',
        colorized: true
        //  extraVars: [
        // 	 DBPasswd: DB_pwd
        //  ]
    }
}

def stagesRun(stage_name,ansible_path){
    def nodeId = "node" +  new SimpleDateFormat("YYYYMMddHHmmss").format(Calendar.getInstance().getTime())
    def errorFlag = false
    while(true)
    {
        if (errorFlag)
        {
            def desc = '''请选择下一步动作指令后点击Proceed,要终止请点击Abort'''
            def inputResp = input id: "input_${nodeId}", 
                                        message: "${stage_name}执行失败,请选择下一步动作:", 
                                        parameters: [choice(choices:['retry','skip'], description: desc, name: 'action')]
            if ('skip' == inputResp)
            {
                return
            }
            if('retry' == inputResp)
            {
                echo "重试"
            }
        }//if (errorFlag)
        try
        {
            "${stage_name}"("${ansible_path}")
            break
        }
        catch(Exception err)
        {
            errorFlag = true
            echo "Caught: ${err}"
        }
    }//while(true)
}

传入的参数不确定的情况

主程序
function = load "${WORKSPACE}/jenkinsfile/common.groovy"
def parmList = [a,b,c,d]		//将要传入的参数放到列表里面
function.stagesRun("flywayUpgradeSql",gitProduct,parmList)	
common.groovy
#!groovy
/**
 * @description: 通过flyway升级数据库
 * @param:  [数据库用户名,密码,jdbc_url,flyway升级sql的路径]
 * @return: null
 */
def flywayUpgradeSql(paramList){
    def dbUser = paramList[0]
    def dbPwd = paramList[1]
    def dbUrl = paramList[2]
    def sqlPath = paramList[3]
    sh """
        source /etc/profile
        [[ ! -d ${sqlPath} ]] && echo "ERROR:${sqlPath} Not Found" && exit 1
        /home/admin/flyway-4.2.0/flyway \\
        -user=${dbUser} -password=${dbPwd} \\
        -url=${dbUrl} -locations=filesystem:${sqlPath} \\
        -baselineOnMigrate=true -validateOnMigrate=false -placeholderReplacement=false \\
        repair migrate
    """
}

//运行stage
def stagesRun(stageName,gitProduct,parmList){
    def errorFlag = false
    while(true)
    {
        if (errorFlag)
        {
            def desc = '''请选择下一步动作指令后点击Proceed,要终止请点击Abort'''
            def inputResp = input id: "input_${BUILD_NUMBER}",
                    message: "${stageName}执行失败,请选择下一步动作:",
                    parameters: [choice(choices:['retry','skip'], description: desc, name: 'action')]
            if ('skip' == inputResp)
            {
                return
            }
            if('retry' == inputResp)
            {
                echo "重试"
                sh """
                    for name in `echo ${gitProduct}`
                    do
                    {
                        name=\${name##*/}
                        cd ${WORKSPACE}/\$name
                        git pull
                     } &
                    done
                    wait
                    cd ${WORKSPACE}/devops && git pull
                """
            }
        }//if (errorFlag)
        try
        {
            "${stageName}"(parmList)
            break
        }
        catch(Exception err)
        {
            errorFlag = true
            echo "Caught: ${err}"
        }
    }//while(true)
}

return this		//这句一定得写,不然不能调用

执行效果

在这里插入图片描述

六、参考

书籍:《Jenkins2权威指南》

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐