首页 > 解决方案 > Jenkins cleanWs 由于权限不清理文件

问题描述

我们使用 Jenkins(除其他外)运行一系列测试作业。对于每个测试,从 Nexus 存储库下载必要的 docker 图像和其他对象。所需的容器和服务是使用 docker-compose 和 maven 构建和执行的。这一切正常,测试按需要运行。

测试后,应清理工作区文件和目录。cleanWs使用插件应该可以做到这一点。但是,默认情况下,这会使用该deferredWipeout选项,这会导致存储库目录的整个副本留在工作区中名为<test-name>-ws-cleanup-<run-ID>. 这些通过将@2、@3 等添加到测试名称而随着时间累积。从逻辑上讲,我添加了选项deleteDirs: truedisableDeferredWipeout: true. 这会产生如下错误:

hudson.AbortException: Cannot delete workspace: Unable to delete '/data/jenkins/workspace/XXXX-batch@2/XXX-batch-ant-core/target/classes/de/ubs/XXX/batch/ant/core/AbstractLicenseCheck.class'. Tried 3 times (of a maximum of 3) waiting 0.1 sec between attempts.

发生这种情况是因为,出于我不完全清楚的原因,创建的某些子目录和文件的所有者“root”具有权限设置为 755(即 rwxr-xr-x)。这些通常是 maven 构建创建的目标目录,但我不确定是否没有其他目录。涉及数千个文件,所以我还没有检查它们……还没有。我可能最终不得不这样做。

为了解决这个问题,清理服务定义被添加到定义构建测试服务的 docker-compose.yml文件中。测试了以下命令:

command: rm -rf * && rm -rf /opt/test/*

这导致了关于 rm 命令的无效选项“c”的模糊错误消息。(??) 否则无效。在检查了其他一些堆栈溢出问题后,我尝试了这个:

command: sh -c "rm -rf * && rm -rf /opt/test/*"

这不会产生错误,但也不会产生预期的效果。使用收益率--verbose选项docker-compose run

2021-03-09 08:29:26 compose.cli.verbose_proxy.proxy_callable: docker inspect_container -> {'AppArmorProfile': '',
2021-03-09 08:29:26  'Args': ['rm', '-rf', '*', '&&', 'rm', '-rf', '/opt/test/*'],
2021-03-09 08:29:26  'Config': {'AttachStderr': True,
2021-03-09 08:29:26             'AttachStdin': True,
2021-03-09 08:29:26             'AttachStdout': True,
2021-03-09 08:29:26             'Cmd': ['rm', '-rf', '*', '&&', 'rm', '-rf', '/opt/test/*'],
2021-03-09 08:29:26             'Domainname': '',
2021-03-09 08:29:26             'Entrypoint': ['/usr/local/bin/mvn-entrypoint.sh'],
2021-03-09 08:29:26             'Env': ['TZ=Europe/Berlin',
2021-03-09 08:29:26                     'CONTAINERED=true',
2021-03-09 08:29:26 ...

坦率地说,这并没有告诉我该命令以某种方式被识别。

另一种方法是尝试将文件和目录的权限更改为 777:

command: echo "<password>" | su -c "chmod -R 777 ."

这在控制台上执行时有效,但在docker-compose.yml或 Jenkins 使用的管道 groovy 脚本中使用时无效。

我不知道我还能尝试什么,如果有任何提示,我将不胜感激。如果需要,我很乐意提供更多详细信息。

标签: dockerjenkins

解决方案


这个问题实际上是一个复合问题。

首先,不能按照 Nisarg Shah 的建议更改所有者和组,因为在容器内没有名为 Jenkins 的用户。

777最终的解决方案是通过以root身份发出命令,将测试中文件的权限设置为(即rwxrwxrwx)。最后 docker-compose.yml 中的命令如下所示:

command: sh -c 'echo "<root-password>" | su root -c "chmod -R 777 ."'

要达到这个阶段需要大量的实验,因为命令由不同的进程解析,包括 docker-compose 和 shell。

如果您没有使用 docker-compose 并且希望在 groovy 管道脚本中做同样的事情,那么以下应该可以工作(它在众多实验之一中为我做了):

sh 'echo "<root-password>" | su root -c "chmod -R 777 ."'

使用上述任何一种方法,并通过在 groovy 管道脚本中添加以下阶段,Jenkins 能够执行所需的清理:

stage('cleanup') {
    cleanWs deleteDirs: true, disableDeferredWipeout: true
}

希望这可以帮助有类似问题的人。

PS 在我们的系统上,jenkins 不在 sudoer 组中。因此使用“su root”。如果您的 jenkins 是 sudoer,那么 sudo 当然也可以解决问题。


推荐阅读