gitlab-CI 管道:尝试删除文件时出现 lftp 错误 550



我在 gitlab.com 环境中使用免费的共享运行器。我有一个 gitlab-CI 管道,它一个接一个地运行以下 lftp 命令:

  • lftp -c "set ftp:ssl-allow no; open -u $USERNAME,$PASSWORD $HOST; glob -a rm -r ./httpdocs/*"
  • lftp -c "set ftp:ssl-allow no; open -u $USERNAME,$PASSWORD $HOST; mirror -R public/ httpdocs --ignore-time --parallel=50 --exclude-glob .git* --exclude .git/"

这些命令的目的是删除 httpdocs 文件夹(以前的文件(的内容,然后上传新的生成工件。

CI 管道从 CMS 触发。有时,内容编辑器会并行更新内容,从而导致许多并行运行的触发器(管道大约需要 3 分钟才能完成(。

然后,管道将开始失败,并显示以下错误:

rm:访问失败:550/httpdocs/build-html-styles.css:没有这样的文件 或目录

发生这种情况是因为另一个管道删除的文件正在排队等待删除。当 httpdocs 文件夹完全为空时,会发生非常相似的错误。这导致我的整个管道失败(第二个上传 lftp 命令根本没有执行(。

失败管道及其输出的示例:

  • #375793957
  • #375793968
  • #375793932
  • #375793930
  • #375793926
  • #375793924

如何防止这种情况发生?使用 lftp 上传工件不是必须的 - 我正在运行node:8.10.0docker 映像。有问题的 Gitlab-ci.yml 文件。

我正在评论简单的文件锁定和简单的主动轮询等待。我没有使用lftp的经验,但是从各种互联网资源中爬出来,我写了以下内容。我看到 lftp 不支持协议中的文件锁定,所以你可以这样:

const="set ftp:ssl-allow no; open -u $USERNAME,$PASSWORD $HOST"
# wait until file exists
while lftp -c "$const; df lockfile"; do sleep 1; done
# create the lockfile
lftp -c "$const; mkdir lockfile"
# the work
lftp -c "$const; glob -a rm -r ./httpdocs/*"
lftp -c "$const; mirror -R public/ httpdocs  --ignore-time --parallel=50 --exclude-glob .git* --exclude .git/"
# remove lockfile
lftp -c "$const; rmdir lockfile"

我使用了mkdirrmdir以及目录而不是文件,因为我不知道如何使用 lftp 创建一个空文件。查找文件和创建文件之间仍然存在争用条件,但它至少应防止两次并发访问。为了保护更多,你可以做一些类似sleep 0.$(printf "%02d" $((RANDOM / 10)))的事情 - 使睡眠时间随机,这样他们就不那么"同时"地创建一个文件。

同样以防万一,我不会镜像到httpdocs目录,而是镜像到一些临时目录,例如tmp=httpdocs_$(uuidgen); lftp "mirror .. $tmp",以后可以重命名为lftp 'rmdir httpdocs; rename $tmp httpdocs",以使部署更安全,停机时间更少(httpdocs空的时间更少(。将来,我建议仅转向更安全/更高级的与远程服务器连接的协议,该协议支持文件锁定。像ssh。或者也许是桑巴舞。

lavv17/lftp问题302主张LFTP跳过此类内容,但这并没有获得任何牵引力。

邮件列表建议

要删除目录,请使用rmdir

在您的情况下:rm -rf httpdocs/(如果需要空文件夹,请后跟mkdir httpdocs(

50 的并发级别与--parallel=50似乎很高。我也在使用 lftp 时遇到了 550 权限错误,降低并发级别为我解决了这个问题。

相关内容

  • 没有找到相关文章

最新更新