【发布时间】:2021-10-16 22:53:02
【问题描述】:
在编写了 post-receive 脚本以查找由 GitLab Runner CI 创建的最新 job.log 文件后,我注意到 post-receive 脚本在找到最新的 job.log 之前被终止或卡住了文件。特别是它不会超出 while 循环。此外,GitLab Runner 会给出 4:Deadline Exceeded 错误。
MWE
MWE 进行完整的部署,并将存储库上传到 GitLab 服务器并在存储库上运行 CI。但是,它还没有很好地推广,因此它(至少)具有以下要求:系统:Ubuntu 20.04,架构:AMD64。
git clone git@github.com:Deployment-Oneliners/Self-host-GitLab-Server-and-Runner-CI.git
cd Self-host-GitLab-Server-and-Runner-CI
git checkout post-receive
rm -r test/libs/*
chmod +x install-bats-libs.sh
./install-bats-libs.sh
./install_gitlab.sh -s -r
./test.sh
然后可以使用以下命令检查 GitLab docker 中 post-receive 脚本的日志:
sudo docker ps -a
sudo docker exec -t -i ab15330e020f /bin/bash
cd /var/opt/gitlab/git-data/repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git/refs/keep-around/9514d16aafc1d741ba6a9ff47718d632fa8d435b
cat post_receive_log.txt
要完全卸载 MWE,可以运行:./uninstall_gitlab.sh -y -h -r。
相关代码
为了确定代码停止的位置,我让post-receive 脚本将大量变量导出到post-receive-log.txt。以下是搜索最新作业日志的循环:
find_job_of_commit() {
local search_path=$1
local searched_commit=$2
echo "in loop search_path=$search_path" >> "post_receive_log.txt"
echo "in loop searched_commit=$searched_commit" >> "post_receive_log.txt"
query_result=$(while ! find "$search_path" -name "job.log" | xargs grep "Checking out $searched_commit"; do sleep 10 ; done)
echo "query_result=$query_result" >> "post_receive_log.txt"
}
输出:
这会输出以下post_receive_log.txt:
repopath_to_artifacts=/var/opt/gitlab/gitlab-rails/shared/artifacts/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35
in loop search_path=/var/opt/gitlab/gitlab-rails/shared/artifacts/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35
in loop searched_commit=eb052e7d
所以基本上可以断定post-receive 脚本在sleep 10 命令期间终止,或者它卡在while 循环中而无法找到文件。更详细的代码显示它实际上在sleep 10 命令之后停止。而且它没有找到最后一份工作(在这次运行中,最新的工作编号是31)。
但是,根据post_receive_log.txt 输出,我可以在 GitLab 泊坞窗内手动运行确切的等待命令,并且它确实工作:
root@127:/var/opt/gitlab/git-data/repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git# while ! find "/var/opt/gitlab/gitlab-rails/shared/artifacts/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35" -name "job.log" | xargs grep "Checking out eb052e7d"; do sleep 10 ; done
/var/opt/gitlab/gitlab-rails/shared/artifacts/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35/2021_10_16/33/33/job.log:Checking out eb052e7d as master...
假设一
我认为repopath_to_artifacts 的文件路径中的@ 符号在命令行中的处理方式与在 bash 脚本中的处理方式不同,导致 bash 中的路径无效/不存在,但 CLI 中的路径有效。
假设二
所以我的第二个想法是 post-receive 在 GitLab 几秒钟后被终止。 4:Deadline Exceeded 消息证实了这一点:
假设三
find 命令使用某种不会在单个 shell 脚本中更新的目录图像。 (对我来说似乎不太可能,也没有解释为什么post-receive 脚本会停止)。但是,如果我手动(在 Docker 中)运行 post-receive 脚本,则手动测试证实了这一点:
/var/opt/gitlab/git-data/repositories/@hashed/d4/73/d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35.git
/opt/gitlab/embedded/service/gitlab-shell/hooks/post-receive.d/./post-receive
f818b5eabfed71a70923bbf5186e31fc0806b6bc\n f818b5eabfed71a70923bbf5186e31fc0806b6bc\n repo_to_test_runner
这对于失败和成功的工作都适用。即使在 post-receive 作业未成功终止之后,在之前无法找到的提交上也是如此。
问题
为什么post-receive 文件会意外终止或卡在while 循环中?
【问题讨论】:
-
在我看来你的整个脚本只是
while ! find -name "job.log" | xargs grep "$commit"; do sleep 10 ; done。为什么find+ 一些奇怪的'\n'+[[ ! -z grep?用 shellcheck 检查你的脚本! -
您的建议大大简化了代码。谢谢!代码仍会意外终止(或卡在 while 循环中),而手动运行命令确实会导致找到文件并终止 while 循环。你问的像
\n这样的工件存在,因为我将包含多个文件路径的字符串拆分为一个数组,以调试每个扫描文件的 while 循环,并改为测试 for 循环,以防我的condition在 while 循环中导致问题。
标签: bash docker gitlab gitlab-ci git-post-receive