Bamboo 限制跨分支的并发构建

Bamboo Limit Concurrent Builds Across Branches

我们有少量用于集成测试的共享数据库和大量共享这些数据库的分支。有什么方法可以防止 Bamboo 同时尝试 运行 使用同一数据库的多个分支?

当并行构建多个分支 运行 时,它们会互相破坏并失败。

有未完成的功能请求BAM-12071 and BAM-2423等待 Atlassian 实施解决方案。

与此同时,我们基于使用老式文件(实际上是目录)锁定为此设计了一个快速而肮脏的解决方法。每个资源都在作业或分支配置中使用变量名称 gatekeeper.resource 定义,在构建过程开始时,"Gatekeeper" 阶段使用公共文件中的目录名称检查所需资源是否可用一个普通的服务器。当目录名称存在时,资源正在使用中。后续构建阶段的第一个任务将资源名称创建为一个空目录,最后一个任务将其删除。在资源空闲之前,其他构建无法继续通过第一阶段,从而停止并发构建。不利的是它确实捆绑了当地的竹子代理商,并且并非完全万无一失,但在 99% 的时间里确实为我们工作。如果资源变量定义正确,它甚至可以跨构建计划工作。

它被定义为针对 linux 实例的 SSH 任务:

# This Gatekeeper stage prevents concurrent builds against a resource 
# by looking for a directory instance in a common file area.
# If the directory exists the build cannot proceed until it disappears.
# The build sleeps as long as the directory exists.
#
# The first task in the subsequent stage is to create the directory, and 
# a final task in the build removes it.
# As a failsafe a background half-hourly cron job should remove lock 
# dirs if they exceed 3 x the build time.
#########################################################
# Wait for a random number of seconds 20-120 to reduce (but not eliminate) the chance that multiple competing branch
# builds triggered by timers both see the dir gone and start the unit test job at once and then proceed to clobber each other (i.e a race condition)
# note: bamboo expects output every 3 minutes so do not increase beyond 180 seconds
SLEEPYTIME=$(( ( RANDOM % 100 ) + 20 ))
echo SLEEPYTIME today is $SLEEPYTIME
sleep $SLEEPYTIME
# Wait for the Gatekeeper lock dir to disappear... or be older than 3 hours (previous build may have hung)
file=/test/atlassian/bamboo-gatekeeper/inuse-${bamboo.gatekeeper.resource}
while [ -d "$file" ]
do
  echo $(date +%H:%M:%S) waiting $SLEEPYTIME seconds...
  sleep $SLEEPYTIME
done
exit 0

构建阶段的第一个工作任务(Gatekeeper 之后):

# This will fail if the lock file (actually a directory!) already exists
file=/test/atlassian/bamboo-gatekeeper/inuse-${bamboo.gatekeeper.resource}
mkdir "$file"

构建后构建阶段的最后一步(成功或失败)

file=/test/atlassian/bamboo-gatekeeper/inuse-${bamboo.gatekeeper.resource}
rm -rf "$file"

还有一个故障保护 cron 清理任务,它删除任何早于几个小时(在我们的例子中是 3 个)的资源网关目录。应该不是必需的,但可以防止在没有 运行 最终任务的情况下重新启动 bamboo 本身时无限期地捆绑构建。

# This works in conjunction with bamboo unit tests. It clears any unit test lock files after 3 hours (e.g. build has hung or killed without removing lock file)
15,45 * * * * find /test/atlassian/bamboo-gatekeeper -name inuse* -mmin +180 -delete

gatekeeper.resource可以任意定义名称。在我们的例子中,它是集成测试使用的数据库模式。我们的一些分支机构使用通用测试环境,其他分支机构有自己的实例。此解决方案阻止使用公共环境的分支并发执行,同时允许具有自己环境的分支继续进行。

将并发构建限制为特定数量并不是一个完整的修复,但在 Atlassian 实施永久解决方案之前,它足以让我们解决这个问题。我希望它能帮助别人。