首页 文章

如何将每个Jenkins构建实例限制为最多x个节点

提问于
浏览
0

是否可以限制作业的构建实例在最多x个节点上运行?

例如,假设我有20个奴隶和一个名为“ParentJob”的父作业 . “ParentJob”配置为在任何可用的从属服务器上同时运行20个子作业,称为“ChildJob” . 由于我需要启动多个ParentJobs,我想将子作业限制为每个ParentJob构建实例5个节点 .

基本上,我想同时启动ParentJob#1,#2和#3,但我不希望从ParentJob#1生成的所有ChildJobs都占用所有从属 . ParentJob#1的ChildJobs应使用节点1-5,ParentJob#2的ChildJobs应使用节点6-10,ParentJob#3的ChildJobs应使用节点11-15 .

我看过Throttle Concurrent Builds插件和Lockable Resource插件,但它们似乎没有解决我想要实现的目标 . 它们似乎只在工作级别工作,而不是在构建级别 .

我的另一个选择是编写Groovy代码来获取x个可用节点,将它们唯一标记,并在这些节点上运行子作业 . 作业完成后,我可以清除标签,以便其他版本可用 .

是否有更简单的选项或插件可以做到这一点?也许我过于复杂了 .

希望这不是太混乱 . 提前致谢 .

1 回答

  • 0

    由于我找不到任何东西,我为我的管道工作编写了以下Groovy脚本 .

    此脚本将获取前3个没有“TESTING _ . *”标签的从属并附加新标签 . 然后,仅在这些节点上执行作业,而不占用我的服务器场中的所有从属服务器 . 作业完成后,标签将被删除 .

    node ("master") {
        def new_label = "TESTING_" + org.apache.commons.lang.RandomStringUtils.random(7, true, true)
        echo "New label for slaves: " + new_label
    
        try {
            stage('Reserve slaves') {
                reserve_slaves(3, new_label)
            }
    
            stage('Smoke tests') {
                // Do your parallel jobs here
                // Pass in new_label to the job
            }
        }
    
        finally {
            stage('Return slaves') {
                remove_label_from_slaves(new_label)
            }
        }
    }
    
    
    def reserve_slaves(number_of_slaves, new_label) {
        def label_prefix = "TESTING_"
        def slaves_with_new_label = 0
    
        while (slaves_with_new_label < number_of_slaves) {
            for (slave in jenkins.model.Jenkins.instance.slaves) {
                def current_labels = slave.getLabelString()
    
                if (!current_labels.contains(label_prefix)) {
                    echo "Adding label '${new_label}' to " + slave.name + ". Existing labels are: ${current_labels}"
                    slave.setLabelString(current_labels + " " + new_label)
                    slaves_with_new_label += 1
                }
    
                if (slaves_with_new_label >= number_of_slaves) {
                    break
                }
            }
    
            if (slaves_with_new_label < number_of_slaves) {
                echo "Waiting for nodes to become available..."
                sleep(10) // in seconds
            }
        }
    }
    
    
    def remove_label_from_slaves(label) {
        for (slave in jenkins.model.Jenkins.instance.slaves) {
            def current_labels = slave.getLabelString()
    
            if (current_labels.contains(label)) {
                echo "Removing label '${label}' from " + slave.name + ". Existing labels are: ${current_labels}"
    
                current_labels = current_labels.replace(label, '')
                slave.setLabelString(current_labels)
            }
        }
    }
    

相关问题