如何检查指定Jenkins Job工作区是否被其他任务占用?
检查Jenkins指定工作区是否被占用并实现任务互斥/等待逻辑
核心思路
通过Jenkins Pipeline的Groovy脚本,遍历当前所有正在运行的Job实例,对比它们的工作区路径与目标路径c:\workspace,判断是否有任务正在占用该工作区。根据需求可选择直接终止当前任务,或循环等待直到工作区空闲后继续执行。
实现1:检查到占用直接终止流水线
在JobA的Pipeline开头添加以下脚本,一旦检测到目标工作区被占用,立即终止当前流水线:
// 目标工作区路径(Windows路径需转义反斜杠,或改用正斜杠) def targetWorkspace = 'c:\\workspace' // 获取所有正在运行的Jenkins Job实例 def runningJobs = Jenkins.instance.getAllItems(Job.class).findAll { job -> job.isBuilding() } // 检查是否有运行中任务占用目标工作区 def workspaceOccupied = runningJobs.any { job -> def build = job.getLastBuild() build != null && build.getWorkspace()?.getRemote() == targetWorkspace } if (workspaceOccupied) { error "工作区 ${targetWorkspace} 正在被其他任务占用,终止当前流水线" } // 后续JobA的流水线逻辑...
实现2:检查到占用后等待,直到空闲再运行
如果需要等待占用任务完成后再执行JobA,可在上述基础上添加循环等待逻辑:
def targetWorkspace = 'c:\\workspace' def checkInterval = 30 // 检查间隔(秒) def maxWaitTime = 3600 // 最大等待时长(秒,避免无限等待) def waitStartTime = System.currentTimeMillis() while (true) { def runningJobs = Jenkins.instance.getAllItems(Job.class).findAll { job -> job.isBuilding() } def workspaceOccupied = runningJobs.any { job -> def build = job.getLastBuild() build != null && build.getWorkspace()?.getRemote() == targetWorkspace } if (!workspaceOccupied) { echo "工作区 ${targetWorkspace} 已空闲,开始执行JobA" break } // 检查是否超过最大等待时长 def elapsedTime = (System.currentTimeMillis() - waitStartTime) / 1000 if (elapsedTime >= maxWaitTime) { error "等待工作区超时(已等待${maxWaitTime}秒),终止流水线" } echo "工作区 ${targetWorkspace} 被占用,${checkInterval}秒后再次检查..." sleep(checkInterval) } // 后续JobA的流水线逻辑...
注意事项
- 脚本权限配置:需给执行Pipeline的用户授予
Jenkins.ScriptApproval权限,否则无法调用Jenkins.instance相关API。 - 路径准确性:如果Jenkins工作区带有分支/构建号后缀(如
c:\workspace\JobB\main),需调整targetWorkspace为实际路径。 - 复杂场景扩展:后续如需支持多工作区、任务分组互斥等,可基于此逻辑扩展,比如维护全局占用状态变量。
内容的提问来源于stack exchange,提问作者Yung Driller
相关产品推荐
相关产品推荐

