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

时间:2019-12-11 17:11:55

标签: linux gitlab-ci lftp

我正在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命令根本不执行)。

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

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

2 个答案:

答案 0 :(得分:1)

我评论了简单的file locking和简单的主动轮询等待。我没有lftp的经验,但是从this之类的各种Internet资源开始,我写了以下内容。我看到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。也许是桑巴舞。

答案 1 :(得分:0)

lavv17/lftp issue 302主张lftp跳过此类内容,但这并没有引起任何注意。

mailing list suggests

  

要删除目录,请使用rmdir

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

相关问题