Jenkins之pipeline

jenkins使用pipeline

tips:

对于刚开始接触jenkins的,总可能会有很多问题,这里我总结一下,方便各位按需匹配.

安装

建议用war包安装,安装jenkins新版本,可以参考https://www.jenkins.io/zh/doc/book/installing/, war包地址https://updates.jenkins-ci.org/download/war/

jenkins api

我目前使用的是python的jenkinsapi,大部分功能可以实现哈

linux安装这里我有一个自动注册的脚本,windows安装可以下载jnlp文件双击点击安装成服务,但是windows里面是system用户,需要注意下环境变量和家目录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
MASTER_URL="xxx"
MASTER_USERNAME='jenkins'
MASTER_PASSWORD='xxx'
WORKD_DIR='/data/jenkins'
IP=$(hostname -i|tr ' ' '\n'|grep -E '^172.31')
NUM_EXECUTORS=2

# Download CLI jar from the master
curl ${MASTER_URL}/jnlpJars/jenkins-cli.jar -o $WORK_DIR/jenkins-cli.jar

# Create node according to parameters passed in
export JENKINS_USER_ID=$MASTER_USERNAME
export JENKINS_API_TOKEN=$MASTER_PASSWORD
if [[ -f " /usr/lib/systemd/system/jenkins-slave.service" ]];then
    echo 'already init the jenkins'
else
    cat <<EOF | java -jar $WORK_DIR/jenkins-cli.jar -s "${MASTER_URL}" create-node "$IP" |true
<slave>
  <name>${NODE_NAME}</name>
  <description></description>
  <remoteFS>/data/jenkins</remoteFS>
  <numExecutors>${NUM_EXECUTORS}</numExecutors>
  <mode>NORMAL</mode>
  <retentionStrategy class="hudson.slaves.RetentionStrategy\$Always"/>
  <launcher class="hudson.slaves.JNLPLauncher">
    <workDirSettings>
      <disabled>false</disabled>
      <internalDir>remoting</internalDir>
      <failIfWorkDirIsMissing>false</failIfWorkDirIsMissing>
    </workDirSettings>
  </launcher>
  <label></label>
  <nodeProperties/>
  <userId>${USER}</userId>
</slave>
EOF
    SECRET=$(curl -u $MASTER_USERNAME:$MASTER_PASSWORD http://xxx/computer/$IP/slave-agent.jnlp 2>/dev/null|xmllint  --format -|sed -nr '/hudson.remoting.jnlp.Main/{n;p}'|awk -F '<argument>|</argument>' '{print $2}')
    cat <<EOF > /usr/lib/systemd/system/jenkins-slave.service
[Unit]
Description="used for up and down jenkins slave"
After=network.target

[Install]
WantedBy=multi-user.target

[Service]
EnvironmentFile=/etc/environment
Type=simple
ExecStart=/usr/bin/java -jar /data/jenkins/remoting.jar -jnlpUrl http://xxx/computer/$IP/slave-agent.jnlp -secret $SECRET -workDir "/data/jenkins"
TimeoutStartSec=120
TimeoutStopSec=120
TimeoutSec=120
EOF
# Creating the node will fail if it already exists, so |true to suppress the
# error. This probably should check if the node exists first but it should be
# possible to see any startup errors if the node doesn't attach as expected.
    systemctl daemon-reload
    systemctl reset-failed
    systemctl enable jenkins-slave
    systemctl start jenkins-slave
fi

下载安装常用的插件

jenkins web操作

不再赘述,参考https://www.jenkins.io/zh/doc/book/getting-started/ 如果没有,可以手动上传Hpi文件http://updates.jenkins-ci.org/download/plugins/

变量设置和使用

变量使用方法

变量可以在配置job的时候使用到,常见的全局变量在http://JENKINS_URL:JENKINSPORT/env-vars.html/ windows %变量名% 比如%BRANCH_NAME% linux ${变量名} 比如${BRANCH_NAME} 插件定义的参数 $a 环境变量可以通过env.xxx = "xxx"设置

全局变量

全局变量在mange jenkinsConfigure systemglobal properties里面设置

配置gitlab token方法

  • 安装git和gitlab插件
  • gitlab–用户头像–settingAccess tokens添加一个token用户同步代码
  • jenkinsmange jenkinsconfigure system–搜索Gitlab,添加对应的token

使用jenkins的CLI文本模式

参考官方文档 https://www.jenkins.io/zh/doc/book/managing/cli/ 建议还是使用程序API代码集成

使用blue ocean功能

参考官方文档 2.7以上插件里面搜索blue ocean安装 使用blue ocean,通过jenkins_url/blue打开或者经典UI job的左侧 打开blue ocean

pipeline的使用

在创建project的时候,我们选择流水线或者Pipeline, 就可以生成一个pipeline的job,pipeline的使用非常重要,贯穿所有jenkins的日常

pipeline生成器

url为JENKINS_URL:JENKINS_PORT/pipeline-syntax, 如果忘记了就随便打开一个pipeline job,在编辑框左下角有一个Pipeline syntax打开就好了,这个功能很棒!

pipeline的语法

tip:

  • pipeline是groovy语言加了一层壳实现的jenkins描述语言,用于和jenkins进行交互,web能点的选择的都可以在jenkins pipeline里面编写,代码即实现
  • pipeline通过stage来分段,通过step来分步骤,整个流程非常清晰
一个典型的pipeline
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!groovy
import jenkins.model.Jenkins
pipeline {
  agent{ } // 指定在哪个节点运行
  environment { } // 可以在这使用一些变量
  options { } // 这里指定构建的一些参数
  parameters { } // 这里指定构建的一些参数
  stages { stage ('my stage') {
    steps {
      script { }
    }
  }
}}
agent部分
1
2
3
4
5
6
7
agent { any }
agent {
  node {
    label 'xxx' //你的节点
    customWorkspace 'xxx' //你的目录
  }
}
指定parameterized参数(需要下载Publish Over SSH插件)
1
2
3
4
parameters {
  string(name:'NAME', defaultValue:'DEFAULT', description:'DESCRIPTION')
  booleanParam(name:'NAME', defaultValue: 'TRUEORFALSE', description:'DESCIPTION')
}
扩展环境变量

environment { EN1 = '' EN2 = '' }

指定job的一些build选项
1
2
3
4
5
6
options {
    timestamps ()
    timeout(time: 240, unit: 'MINUTES')
    disableConcurrentBuilds()
    buildDiscarder(LogRotator(numToKeepStr: '100'))
}
编写stage
stage部分大的框架如下, 如果少了可能会报错
1
2
3
4
5
6
7
stages {
    stage {
       steps {
           script {}
       }
   }
}
stage条件执行
1
2
3
stage ("xxx") {
    when { equals expected: "true", actual: "${params.xxx}" }
}
steps里面常用操作
切到分支

checkout([$class: 'GitSCM', branches: [name: '*/master']], doGenerateSubmoduleConfigurations: false, extentions:\[\[$class: 'RelativeTargetDirectory', relativeTargetDir: 'xxx'\]\], submoduleCfg:[], userRemoteConfigs: \[\[credentialsId: 'YouCredentialID', url: 'git address\]\] )

scripts里面常用操作
判断是windows机器还是linux机器

if (isUnix()){} else {}

获取脚本的输出
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
scriptOut = sh return Stdout: true, script:'Your script execute'
scriptOut = bat label:'', return Stdout: true, script:'Your script execute'
one example( get newest branch name):
if(isUnix()){
    src_newest_branch = sh returnStdout: true,script:"python3 get_newest_branch.py"
} else {
    src_newest_branch = bat label: '', returnStdout: true, script: """@echo off
py -3 get_newest_branch.py"""
}
//trim是去掉常见的非法字符比如空格''等
src_newest_branch=src_newest_branch.trim()
//打印变量
获取上一次成功的build number
1
2
3
if (Jenkins.instance.getItem("${JOB_NAME}").getLastSuccessfulBuild() != null){
    lastSuccessBuild = Jenkins.instance.getItem("${JOB_NAME}").getLastSuccessfulBuild().getNumber()
}
pipeline自己进行get请求
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!groovy
import jenkins.model.Jenkins
import groovy.json.JsonSlurper
def getABNode() {
    def ab_node_url ="http://xxx";
    def postmanGet = new URL(ab_node_url);
    def getConnection = postmanGet.openConnection();
    getConnection.requestMethod = 'GET';
    getConnection.setRequestProperty('Accept', 'application/json');

    def apply_result = new JsonSlurper().parseText(getConnection.inputStream.text);
    if(apply_result['status']==200) {
        println(apply_result['message'])
        println(apply_result)
        println(apply_result['data'])
    get_node = 'true'
    } else {
        print(apply_result)
        get_node = 'false'
        return ''
    }
}
清理工作空间
1
2
3
4
5
post {
    always {
        cleanWs()
    }
}
使用凭据Credentials
1
2
3
withCredentials([string(credentialsId: 'xxxx', variable: 'xxx'),string(credentialsId: 'xxx', variable: 'xxx')]){
    script { ${xxx} }
}

jenkins和gitlab集成

git或者gitlab可以触发webhook自动构建jenkins job

具体方法不再演示自省百度哈, 有时间再说~ **

其他相关

如果还有其他问题建议自己想想解决办法,可以写一些额外的工具脚本完成扩展,再不行baidu,google,stackoverflow devops需要我们自己大量的动手实践,最好是开发一个平台集成