怎么通过 Jenkins 进行资源的锁定和释放

在日常工作中,开发和测试人员常常需要在多个不同的平台(如linux、aix、windows、solris、hp-ux)上进行开发和问题验证。然而,由于虚拟机资源有限,并不能确保每个开发和测试人员都能访问所有平台的不同版本的虚拟机,这导致准备各种开发和测试环境变得非常耗时。

对于这样的需求,通常会考虑以下几种解决方案:

  1. Docker:虽然Docker是一个不错的选择,但它仅适用于Linux和Windows,不能覆盖所有我们需要的平台(如AIX、Solris、HP-UX)。

  2. 从Artifactory获取Build并通过CI工具安装:由于某些原因,我们目前无法使用Artifactory。

  3. 从源代码构建并安装:这是我们目前可行的解决方案,但需要解决资源锁定和释放的问题。

为了确保在使用过程中环境不被破坏,如果当前有人在使用某台虚拟机,那么这台机器的资源应该被锁定,防止Jenkins调用正在使用的节点。本文主要介绍如何通过Jenkins的Lockable Resources Plugin来实现资源的锁定和释放。

演示Demo

  1. 设置Lockable Resources

    在Jenkins中,进入配置,找到Lockable Resources Manager,添加可锁定资源。

  2. 查看资源池

    Lockable Resources显示有两个可用资源。

  3. 测试锁资源

    这里配置的是参数化类型的Job,可以选择不同平台和仓库进行构建。

    运行第一个Job。

    查看当前可用资源数量,Free resources = 1,看到已经被#47这个Job使用。

    继续运行第二个Job。

    查看当前可用资源数量,Free resources = 0,看到已经被#48这个Job使用。

    关键一步,如果继续运行第三个Job,是否能被继续执行。

    可以看到这个任务没有被执行,通过日志发现,当前正在等待可用的资源。

  4. 测试释放资源

    现在释放一个资源,看第三个Job是否能拿到资源并执行。

    从下图可以看到第三个Job已经运行成功了。

Jenkins Pipeline代码

整个pipeline最关键的部分是如何上锁和释放,这里是通过

lock
input message
来实现的。当前Job只要用户不点击"Yes",就会一直处于未完成状态,其锁会一直生效,直到用户点击"Yes",Job结束,锁也就释放了。

具体可以参考下面的Jenkinsfile。

pipeline {
    agent {
        node {
            label 'PreDevENV'
        }
    }
    options {
        lock(label: 'PreDevENV', quantity: 1)
    }
    parameters {
        choice(
            name: 'platform',
            choices: ['Linux', 'AIX', 'Windows', 'Solris', 'HP-UX'],
            description: 'Required: which platform do you want to build')
        choice(
            name: 'repository',
            choices: ['repo-0.1', 'repo-1.1', 'repo-2.1', 'repo-3.1', 'repo-4.1'],
            description: 'Required: which repository do you want to build')
        string(
            name: 'branch',
            defaultValue: '',
            description: 'Required: which branch do you want to build')
    }
    stages {
        stage('git clone'){
            steps {
                echo "git clone source"
            }
        }
        stage('start build'){
            steps {
                echo "start build"
            }
        }
        stage('install build'){
            steps{
                echo "installing"
            }
        }
        stage('unlock your resource'){
            steps {
                input message: "do you have finished?"
                echo "Yes, I have finished"
            }
        }
    }
}