詹金斯管道的deleteDir()失败,并出现java.nio.file.AccessDeniedException异常

时间:2019-02-10 11:42:22

标签: jenkins jenkins-pipeline

我有一个Jenkins Pipeline工作来构建我的Android项目。
基本步骤是检出项目的存储库,运行docker容器(将主机的存储库文件夹映射到容器中的相应文件夹),在容器中执行脚本并提取工件。

第一步是使用deleteDir()函数删除工作区:

node("jenkins-slaves") {
    deleteDir() // <-------------- HERE

    stage('checkout repo') {
        // REDACTED
    }

    // REDACTED
}

但是,在第一次尝试运行它的过程中,我收到以下错误:

[Pipeline] node
Running on jenkins-slave14 in /home/jenkins/workspace/REDACTED
[Pipeline] {
[Pipeline] deleteDir
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.nio.file.AccessDeniedException: /home/jenkins/workspace/REDACTED/app/all-apk/apks
    at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
    at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
    at sun.nio.fs.UnixFileSystemProvider.implDelete(UnixFileSystemProvider.java:244)
    at sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:108)
    at java.nio.file.Files.deleteIfExists(Files.java:1165)
    at hudson.Util.tryOnceDeleteFile(Util.java:290)
    at hudson.Util.deleteFile(Util.java:245)
    at hudson.FilePath.deleteRecursive(FilePath.java:1211)
    at hudson.FilePath.deleteContentsRecursive(FilePath.java:1220)
    at hudson.FilePath.deleteRecursive(FilePath.java:1202)
    at hudson.FilePath.deleteContentsRecursive(FilePath.java:1220)
    at hudson.FilePath.deleteRecursive(FilePath.java:1202)
    at hudson.FilePath.deleteContentsRecursive(FilePath.java:1220)
    at hudson.FilePath.deleteRecursive(FilePath.java:1202)
    at hudson.FilePath.access$1000(FilePath.java:197)
    at hudson.FilePath$14.invoke(FilePath.java:1181)
    at hudson.FilePath$14.invoke(FilePath.java:1178)
    at hudson.FilePath$FileCallableWrapper.call(FilePath.java:2750)
    at hudson.remoting.UserRequest.perform(UserRequest.java:208)
    at hudson.remoting.UserRequest.perform(UserRequest.java:54)
    at hudson.remoting.Request$2.run(Request.java:360)
    at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused: java.io.IOException: Unable to delete '/home/jenkins/workspace/REDACTED/app/all-apk/apks'. Tried 3 times (of a maximum of 3) waiting 0.1 sec between attempts.
    at hudson.Util.deleteFile(Util.java:250)
    at hudson.FilePath.deleteRecursive(FilePath.java:1211)
    at hudson.FilePath.deleteContentsRecursive(FilePath.java:1220)
    at hudson.FilePath.deleteRecursive(FilePath.java:1202)
    at hudson.FilePath.deleteContentsRecursive(FilePath.java:1220)
    at hudson.FilePath.deleteRecursive(FilePath.java:1202)
    at hudson.FilePath.deleteContentsRecursive(FilePath.java:1220)
    at hudson.FilePath.deleteRecursive(FilePath.java:1202)
    at hudson.FilePath.access$1000(FilePath.java:197)
    at hudson.FilePath$14.invoke(FilePath.java:1181)
    at hudson.FilePath$14.invoke(FilePath.java:1178)
    at hudson.FilePath$FileCallableWrapper.call(FilePath.java:2750)
    at hudson.remoting.UserRequest.perform(UserRequest.java:208)
    at hudson.remoting.UserRequest.perform(UserRequest.java:54)
    at hudson.remoting.Request$2.run(Request.java:360)
    at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at ......remote call to jenkins-slave14(Native Method)
    at hudson.remoting.Channel.attachCallSiteStackTrace(Channel.java:1654)
    at hudson.remoting.UserResponse.retrieve(UserRequest.java:311)
    at hudson.remoting.Channel.call(Channel.java:905)
    at hudson.FilePath.act(FilePath.java:987)
Caused: java.io.IOException: remote file operation failed: /home/jenkins/workspace/REDACTED at hudson.remoting.Channel@16d096ce:jenkins-slave14
    at hudson.FilePath.act(FilePath.java:994)
    at hudson.FilePath.act(FilePath.java:976)
    at hudson.FilePath.deleteRecursive(FilePath.java:1178)
    at org.jenkinsci.plugins.workflow.steps.DeleteDirStep$Execution.run(DeleteDirStep.java:77)
    at org.jenkinsci.plugins.workflow.steps.DeleteDirStep$Execution.run(DeleteDirStep.java:69)
    at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution$1$1.call(SynchronousNonBlockingStepExecution.java:49)
    at hudson.security.ACL.impersonate(ACL.java:260)
    at org.jenkinsci.plugins.workflow.steps.SynchronousNonBlockingStepExecution$1.run(SynchronousNonBlockingStepExecution.java:46)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Finished: FAILURE

此问题的根本原因是什么,我该如何解决?

1 个答案:

答案 0 :(得分:0)

删除错误通常是由于权限不足或某人/某物锁定文件引起的。

我注意到Jenkins尝试删除失败的文件夹是由构建脚本在容器中动态创建的。该文件夹及其下面的所有文件都是使用root / root(用户/组)创建的。

这帮助我了解了此问题的根本原因-管道正在使用jenkins / jenkins(用户/组)运行,并且无法删除由其他用户(在我的情况下为root / root)创建的文件/文件夹。

我想出的解决方案是使用主机系统使用的同一用户(属于同一组)(我的容器操作系统基于Alpine)创建docker映像:

RUN addgroup -S -g 6002 jenkins
RUN adduser -S -u 6002 -G jenkins jenkins
USER jenkins

请注意,GID和UID(在上例中均为6002)必须与主机中的ID匹配。为了找到它们,您可以使用以下命令:

id -u jenkins  
id -g jenkins  

来自documentation

  

USER指令设置用户名(或UID),并可选地设置   运行映像以及任何RUN,CMD时要使用的用户组(或GID)   以及Dockerfile中紧随其后的ENTRYPOINT指令。

执行此步骤后,容器中由构建脚本创建的所有文件/文件夹都将使用匹配的主机用户-主机OS可以毫无问题地操作/删除它们。