Jenkins Pipeline

作者: LinuxSuRen | 来源:发表于2017-11-28 14:51 被阅读0次
    • 介绍

    本文介绍如何在Jenkins中使用pipeline插件。

    本文的Jenkins是基于docker安装的,如果您对这部分感兴趣,请参考《Docker安装应用》。

    Domain Specific Language(DSL)

    • 什么是Pipeline

    Jenkins Pipeline是一套插件,支持实现和持续集成作为流水线应用到Jenkins。Pipeline提供了一套可扩展的工具。

    • 为什么要用Pipeline

    根本上来说,Jenkins是一个支持很多自动化模式的引擎。Pipeline增加了一套强大的工具到Jenkins中,支持用户从见的持续集成到全面的持续集成。通过模块化一些列相关的任务,用户可以利用很多Pipeline的特性。

    代码:Pipelines通过代码来实现,并通常可以由版本控制系统(svn、git等)来管理。

    可暂停:Pipelines可以暂停(停止),并且可以在运行之前接收人工输入或者等待同意。

    • Pipeline表达式

    Step

    是一个单一任务,告诉Jenkins该做什么。例如,在step中执行shell命令make。当一个插件扩展了Pipeline DSl,就意味着可以使用新的step。

    Node

    大多数工作是在一个或者多个节点(node)中完成的。

    • 语法

    Jenkins的流水线(pipeline)采用groovy语法来编写。逻辑判断、循环、异常等功能都是具备的,另外,熟悉groovy的人就明白这和Java的写法有一定的相似。

    下面我介绍一些流水线的步骤(或者函数),首先介绍的是在插件workflow-basic-steps-plugin中的。我们从插件的名称上也能看到,这些流水线步骤大多是基础、简单的。首先,给出我研究时的版本信息:

    <pre class="lang:default decode:true "><groupId>org.jenkins-ci.plugins.workflow</groupId>
    <artifactId>workflow-basic-steps</artifactId>
    <version>2.7-SNAPSHOT</version></pre>

    以便各位依据本文可以进一步学习Jenkins流水线插件的源码。

    • 环境变量

    <pre class="lang:default decode:true ">node {
    echo env.JENKINS_HOME
    sh 'echo $JENKINS_HOME'

    echo env.JOB_NAME
    echo env.NODE_NAME
    echo env.NODE_LABELS
    echo env.WORKSPACE
    echo env.JENKINS_URL
    echo env.BUILD_URL
    
    env.SUREN_VER = '12'
    echo env.SUREN_VER
    

    }</pre>

    上面的示例中,给出了如何使用内置的环境变量和自定义环境变量的做法

    • 工具

    <pre class="lang:default decode:true">node() {
    tool name: 'JDK8_Linux', type: 'jdk'
    tool name: 'maven339_linux_dir', type: 'maven'
    echo 'hello'
    }</pre>

    上面的pipeline指定要工具jdk和maven的名称(在Global Tool Configuration中配置)。

    对应的实现类为ToolStep,该类被final关键字所修饰,因此是不能做扩展的了。

    • 属性

    <pre class="lang:default decode:true ">node {
    echo 'hello'
    }

    properties([
    buildDiscarder(
    logRotator(
    artifactDaysToKeepStr: '',
    artifactNumToKeepStr: '',
    daysToKeepStr: '5',
    numToKeepStr: '10'
    )
    ),
    pipelineTriggers([
    cron('H 3,12,17 * * *')
    ])
    ])</pre>

    • 环境变量

    <pre class="lang:default decode:true crayon-selected">node() {
    env.JDK_HOME = "${tool '8u131'}"
    env.PATH="${env.JDK_HOME}/bin:${env.PATH}"

    echo env.JDK_HOME
    echo env.PATH
    sh 'java -version'
    

    }

    node('bimpm_deploytodev') {
    def pass_bin = '/opt/pass/bin'
    env.PASS_BIN = pass_bin

    stage('Clean') {
        sh 'rm -rfv $PASS_BIN'
    }
    

    }</pre>

    • 拷贝成品

    <pre class="lang:default decode:true">node {
    stage('Copy') {
    step([$class: 'CopyArtifact', fingerprintArtifacts: true, flatten: true, projectName: 'BIM_PMJF/BIM-PMJF-BUILD/BIM_PMJF_DISCOVERY', selector: [$class: 'StatusBuildSelector', stable: false], target: '/opt/pass/bin'])
    }
    }</pre>

    实现类为ArtifactArchiverStep

    • 循环

    <pre class="lang:default decode:true ">node('suren') {
    def dev_path = '/opt/suren/bin'
    def services = [
    [
    'name': 'admin',
    'project': 'admin',
    'port': '7002',
    'jarName': 'admin'
    ]
    ];

    stage('Copy Artifact') {
        for(service in services){
            step([$class: 'CopyArtifact', fingerprintArtifacts: true, flatten: true,
                projectName: service.project,
                selector: [$class: 'StatusBuildSelector', stable: false],
                target: dev_path + '/' + service.name
            ])
        }
    }
    
    stage('Stop Service') {
        for(service in services){
           sh 'fuser -n tcp -k ' + service.port + ' > redirection &'
        }
    }
    
    stage('Start Service') {
        for(service in services){
            sh 'cd ' + pass_bin + '/' + service.name + ' && nohup nice java -server -Xms128m -Xmx384m \
                -jar ' + service.jarName + '.jar \
                --server.port=' + service.port + ' $> initServer.log 2>&1 &'
        }
    }
    

    }</pre>

    上面的例子,展示了如何在jenkins pipeline中调用循环语句,实现批量操作。

    • 参数化构建

    <pre class="lang:default decode:true ">properties([[$class: 'JobRestrictionProperty'],
    parameters([run(description: '',
    filter: 'ALL',
    name: 'Name',
    projectName: 'Project')]),
    pipelineTriggers([])]
    )</pre>

    • 并行

    <pre class="lang:default decode:true">node {
    stage('Start Service') {
    parallel 'test': {
    echo 'test'
    }, 'deply': {
    echo 'deply'
    }
    }

    parallel 'one' : {
        stage('one') {
            echo 'one'
        }
    }, 'two' : {
        stage('two') {
            echo 'two'
        }
    }
    

    }

    parallel 'one': {
    node{
    stage('one') {
    echo 'one'
    }
    }
    }, 'two': {
    node {
    stage('two') {
    echo 'two'
    }
    }
    }</pre>

    Jenkins的流水线同时支持节点(node)、阶段(stage)和步骤(step)之间的并行执行。如果多个节点并发执行的话,并发数量会少于当前可用的执行器(exector)数量。

    • 超时

    <pre class="lang:default decode:true">node {
    stage('stage2') {
    timeout(time: 600, unit: 'SECONDS') {
    sleep 20
    echo '2'
    }
    }
    }</pre>

    遇到可能执行时间会比较长的情况,可以通过超时来约定最长的执行时间。

    对应的实现类为TimeoutStep。

    下面介绍的函数在插件workflow-durable-task-step-plugin中,版本信息如下:

    <pre class="lang:default decode:true "><groupId>org.jenkins-ci.plugins.workflow</groupId>
    <artifactId>workflow-durable-task-step</artifactId>
    <version>2.18-SNAPSHOT</version></pre>

    • 工作空间

    当你希望在一个流水线中,对多个工程(例如git工程)做构建以及部署等操作,如果不切换工作空间的话就会发生代码错乱的问题。你可以参考下面的示例代码来解决这个问题:

    <pre class="lang:default decode:true crayon-selected">node{
    stage('suren'){
    ws('suren-a-work') {
    pwd
    }

        ws('suren-b-work') {
            pwd
        }
    }
    

    }</pre>

    实现类为WorkspaceStep,使用final修饰,无法扩展。

    • 执行节点

    Jenkins里可能会配置很多节点(node),而不一定所有的节点都满足你的构建环境要求,这时候就需要来指定节点了:

    <pre class="lang:default decode:true ">node('local') {
    echo 'hello'
    }

    properties([
    buildDiscarder(
    logRotator(
    artifactDaysToKeepStr: '',
    artifactNumToKeepStr: '',
    daysToKeepStr: '5',
    numToKeepStr: '10'
    )
    ),
    pipelineTriggers([
    cron('H 3,12,17 * * *')
    ])
    ])</pre>

    上面的pipeline指定了运行节点的label为local。

    实现类为ExecutorStep,使用final修饰,无法扩展。

    • 异常捕获

    <pre class="lang:default decode:true">node{
    stage('suren'){
    try{
    trigger
    }catch(error){
    echo error.getMessage()
    }
    }
    }</pre>

    这里调用了一个不存在的流水线函数,然后使用catch来捕获并打印错误信息。

    • 远程调试

    安装环境:

    sudo apt-get install -y npm

    jenkins-pipeline --file test.groovy --url http://localhost:8080/jenkins/job/MyJob --credentials admin:123456

    • 参考

    http://cloud.spring.io/spring-cloud-pipelines/

    本文为原创,如果您当前访问的域名不是surenpi.com,请访问“素人派”。

    相关文章

      网友评论

        本文标题:Jenkins Pipeline

        本文链接:https://www.haomeiwen.com/subject/upxebxtx.html