jenkins 脚本编写

基础结构即代码”(具有用代码表示交付/部署管道的基础结构),就像流过它的产品一样。

Jenkins工作流工具是用于创建许多持续交付/部署管道的主要应用程序之一。 这通常是通过为各种管道任务定义一系列单独的作业来完成的。 每个作业都通过Web表单进行配置-填写文本框,从下拉列表中选择条目,等等。然后将一系列作业串在一起,每个作业触发下一个,进入管道。

基础设施即代码”的定义。 作业配置仅作为XML文件存储在Jenkins配置区域中。 这意味着文件不容易阅读或直接修改。 Jenkins应用程序本身提供了用户的主视图以及对它们的访问。

我们通常将Jenkins 2命名为支持流水线代码功能以及其他功能的较新版本。)在本文中,我们将学习如何在Jenkins 2中创建流水线作为代码。这将使用两种不同样式的管道语法(脚本式和声明式)来完成。

我们还将介绍如何在Jenkins外部存储管道代码,但仍然需要Jenkins在更改时运行它,以实现实现DevOps的目标之一。

让我们从基础开始。 Jenkins及其插件通过其自己的编程步骤(Jenkins领域专用语言(DSL))使构建基块可用于您的管道任务。

DSL步骤

工作流插件。 这包括创建一组初始DSL步骤,以允许在Jenkins中编写简单的作业,并通过扩展对简单的管道进行编码。

git步骤,以从源代码控制系统中检索源代码。 清单1显示了其用法的示例:

node ('worker_node1') {
     
     

     stage('Source') {
     
     

         // Get some code from our Git repository
     
     

         git 'http://github.com/brentlaster/roarv2'
     
     

      }
     
     

}

清单1:使用Git步骤的示例管道代码行。

脚本化和声明性

脚本管道

脚本化 。 在最高级别, 脚本化管道被包装在一个节点块中。 这里的节点是指包含Jenkins 代理程序片段并且可以运行作业(以前称为从属实例)的系统。 该节点通过使用标签映射到系统。 标签只是在Jenkins中配置一个或多个节点(通过全局“ 管理节点”部分完成)时添加的标识符。 一个示例如图1所示。

图1:带有标签的节点配置

块是Groovy编程语言中的一种称为闭包的构造(由开括号和闭括号表示)。 实际上,脚本化管道可以包括并利用任何有效的Groovy代码。 作为示例,清单2显示了执行以下操作的脚本管道代码:

检索源代码(通过git pipe步骤);

获取全局定义的Gradle安装的值(通过tool管道步骤),并将其放入Groovy变量中; 和

调用外壳执行它(通过sh管道步骤):

// Scripted Pipeline
       
       

node ('worker_node1') {
       
       

  // get code from our Git repository
       
       

  git 'http://github.com/brentlaster/roarv2'
       
       

   // get Gradle HOME value
       
       

  def gradleHome = tool 'gradle4'
       
       

   // run Gradle to execute compile and unit testing
       
       

  sh "'${gradleHome}/bin/gradle' clean compileJava test"
       
       

}

清单2:使用该工具和sh步骤的脚本语法

gradleHome是一个Groovy变量,用于支持DSL步骤。 可以通过Jenkins定义这样的管道,方法是创建一个新的Pipeline项目,并在新项目页面底部的Pipeline Editor部分中键入代码,如图2所示:

jenkins 执行sql脚本 jenkins 脚本编写_java

图2:定义一个新的管道项目

阶段是将管道划分为逻辑功能单元的一种方式。 它还可以将DSL步骤和Groovy代码组合在一起以实现目标功能。 清单3显示了我们的脚本化管道,其中包含构建阶段的阶段定义和源管理阶段的阶段定义:

// Scripted Pipeline with stages
     
     

node ('worker_node1') {
     
     

  stage('Source') { // Get code
     
     

    // get code from our Git repository
     
     

    git 'http://github.com/brentlaster/roarv2'
     
     

  }
     
     

  stage('Compile') { // Compile and do unit testing
     
     

    // get Gradle HOME value
     
     

    def gradleHome = tool 'gradle4'
     
     

    // run Gradle to execute compile and unit testing
     
     

    sh "'${gradleHome}/bin/gradle' clean compileJava test"
     
     

  }
     
     

}

清单3:带有阶段的脚本语法

舞台视图)中,管道中的每个阶段都具有自己的输出区域。 如图3所示,“阶段视图”输出以矩阵形式组织,每一行代表作业的运行,每一列都映射到管道中定义的阶段:

jenkins 执行sql脚本 jenkins 脚本编写_编程语言_02

图3:定义的阶段和阶段视图输出

此矩阵中的每个单元格(行和列的交集)还显示计时信息,并使用颜色指示成功或失败。 表1显示了每种颜色的关键:

表1:舞台执行的颜色代码

Color

含义

White

阶段尚未运行

Blue stripes

处理中

Green

阶段成功

Red

阶段成功,但下游阶段失败

Red stripes

阶段失败

另外,通过将鼠标悬停在该单元上,弹出窗口将提供有关该阶段执行的更多信息,并带有指向日志的链接,如图4所示:

jenkins 执行sql脚本 jenkins 脚本编写_java_03

图4:钻取阶段输出中的日志

尽管脚本化管道提供了很大的灵活性,并且使程序员感到舒适和熟悉,但是对于某些用户而言,它们确实有其缺点。 特别是:

  • 感觉就像您需要了解Groovy才能创建和修改它们。
  • 对于传统的詹金斯用户来说,学习如何使用它们可能具有挑战性。
  • 它们提供Java样式的回溯以显示错误。
  • 没有内置的生成后处理。

如果您习惯于执行诸如通过Freestyle作业中的后构建处理发送电子邮件通知或归档结果之类的任务,则上面列表中的最后一项可能是一件大事。 如果您的脚本管道代码失败并引发异常,则可能永远无法到达管道末端; 但是,您可以在主要的脚本管道代码周围使用Java样式的try-catch块来处理此问题,如图5所示:

jenkins 执行sql脚本 jenkins 脚本编写_java_04

图5:try-catch块模拟构建后的通知

Notify的最后阶段。 无论管道的早期部分成功还是失败,都将始终执行此阶段。 这是因为try-catch结构将捕获由故障引起的任何异常,并允许控制随后继续。 (Jenkins 2也有一个catchError块,它是try-catch构造的简化的受限版本。)

这种解决方法增加了一种印象,即您需要了解一些编程才能在以前使用Freestyle免费获得的脚本管道中执行操作。 为了简化来自传统Jenkins的开发人员的工作,并从Java / Groovy-ism中脱颖而出,CloudBees和Jenkins社区创建了第二种语法风格来编写管道-声明式。

声明式管道

指令和部分,用于指定管道中所需的项目。 清单4中显示了一个示例性声明式管道:

pipeline {
     
     

  agent { label 'worker_node1' }
     
     

  stages {
     
     

    stage('Source') { // Get code
     
     

      steps {
     
     

        // get code from our Git repository
     
     

        git 'https://github.com/brentlaster/roarv2'
     
     

      }
     
     

    }
     
     

    stage('Compile') { // Compile and do unit testing
     
     

      tools {
     
     

        gradle 'gradle4'
     
     

      }
     
     

      steps {
     
     

        // run Gradle to execute compile and unit testing
     
     

        sh 'gradle clean compileJava test'
     
     

      }
     
     

    }
     
     

  }
     
     

}

清单4:声明性管道示例

agent块,而不是一个node块。 您可以将代理程序和节点视为同一件事,即指定要在其上运行的系统。 (但是,代理程序还包括其他创建系统的方法,例如通过Dockerfiles。)

工具一,在其中声明要使用Gradle的安装(而不是像脚本语法那样将其分配给变量)。 在声明性语法中,不能使用Groovy代码(例如赋值或循环)。 您仅限于结构化的部分/块和DSL步骤。

步骤中的DSL步骤包含在步骤指令中。 这是因为除了阶段中的步骤之外,您还可以声明其他内容。

Jenkins 2:启动和运行手册中的图表,其中包含声明性管道中的所有部分。 读取此图表的方式是,需要带有实线边框的项目,而带有虚线边框的项目是可选的:

图6:声明性管道部分的示意图

环境设置环境变量,而工具声明我们要使用的工具应用程序。 我们不会在这里详细介绍每一个细节,但是这本书有整整一章关于声明性管道。

帖子部分。 这可以模拟Freestyle作业中的后生成处理功能,并且不需要像在脚本管道中使用的try-catch构造那样的语法。 还要注意, post块也可以在阶段结束时发生。

这种明确定义的结构为在Jenkins中使用声明性管道提供了多个优势。 它们包括:

  • 从Freestyle到代码管道的转换更容易,因为您在声明所需内容(类似于在传统Jenkins中填写表单的方式);
  • 更严格,更清晰的语法/要求检查; 和
  • 与新的Blue Ocean图形界面更紧密地集成(管道图中结构良好的部分更易于单个图形对象使用)。

您可能想知道声明性管道的缺点是什么。 如果您需要超出声明性语法所允许的范围,则必须采用其他方法。 例如,如果您想为变量分配一个值并在管道中使用它,则不能使用声明性语法。 有些插件还可能需要某种东西才能在管道中使用它们。 因此,它们与声明性语法不直接兼容。

脚本块。 声明性管道中脚本块中的代码可以是任何有效的脚本语法。

共享管道库 )。 还有一些其他方法,这些方法受到的制裁较少-意味着将来可能不会支持它们。 (如果您有兴趣了解更多信息,那么“ Jenkins 2:启动并运行”一书详细介绍了共享库和其他替代方法。)

Jenkinsfile的外部文本文件中。 然后可以将该文件与源代码一起存储在所需分支的同一存储库中。

詹金斯档案

Jenkinsfile的外部文件中。 这样,我们便可以将管道代码视为其他任何文本文件,这意味着可以将其存储在源代码管理中并在源代码管理中进行跟踪,并进行常规的过程(例如代码审查)。

此外,流水线代码可以与产品源一起存储并与之一起使用,从而使我们可以将流水线作为基础结构即代码来实现。

图7显示了存储在源代码控制存储库中的Jenkins文件:

jenkins 执行sql脚本 jenkins 脚本编写_jenkins 执行sql脚本_05

图7:源代码管理中的Jenkinsfile

源代码管理中Jenkinsfile的内容如图8所示:

图8:示例Jenkinsfile

scm checkout步骤。 这是您可以在Jenkinsfile中使用的快捷方式。 由于Jenkinsfile与它将在其上运行的代码位于相同的存储库(和分支)中,因此它已经假定这是应从中获取源代码的位置。 这意味着我们不需要明确地告诉它该信息。

Multibranch Pipeline类型的项目,并通过作业配置的“ 分支源”部分将其指向带有Jenkinsfile的源存储库。 图9显示了两个步骤:

jenkins 执行sql脚本 jenkins 脚本编写_编程语言_06

图9:创建和配置多分支管道

然后,Jenkins将扫描存储库中的每个分支,并检查该分支是否具有Jenkinsfile。 如果是这样,它将在Multibranch Pipeline项目中自动创建并配置一个子项目,以运行该分支的管道。 图10显示了运行扫描并寻找Jenkinsfiles以在多分支管道中创建作业的示例:

图10:Jenkins检查Jenkinsfiles以在多分支管道中自动设置作业

图11显示了针对Jenkins文件和源存储库执行后的多分支管道中的作业:

图11:基于源代码分支中的Jenkinsfiles自动创建的多分支管道作业

使用Jenkinsfiles,我们可以实现将基础架构(或至少是管道定义)视为代码的DevOps目标。 如果需要更改管道,则可以像在其他文件中一样在源代码控制中拉,编辑和推送Jenkins文件。 我们还可以在管道脚本上执行诸如代码审查之类的事情。

使用Jenkinsfiles有一个潜在的弊端:在外部文件中而不是在Jenkins应用程序环境中工作时,提前发现问题可能更具挑战性。 解决此问题的一种方法是首先在Jenkins应用程序中将代码开发为管道项目。 然后,您可以随后将其转换为Jenkinsfile。 此外,还有一个声明性管道短绒应用程序,您可以针对Jenkins之外的Jenkinsfiles运行它,以及早发现问题。

结论

Jenkins 2:启动并运行》一书,以获取有关使用此技术为DevOps赋权的更多示例和说明。在您的组织中。

翻译自: https://opensource.com/article/18/8/devops-jenkins-2

jenkins 脚本编写