jupierce/openshift-jenkins-pipeline-dsl

Leaking file handle / file lock issue - unable to delete temp file

Closed this issue · 9 comments

Hello,

I am giving this plugin a test. I am running into a file lock failure below. Note oc and jenkins are running in windows. Even after the job completes the file cannot be deleted because it is in use by the jenkins process.

Pipeline script (directly in job):

openshift.withCluster('Sandbox') {
    openshift.withProject( 'dev-myuser' ) {
        println openshift.selector('route', 'helloworld-rte-act').object()
    }
}

[Pipeline] echo

[Pipeline] node
Running on master in C:\Users\myuser.jenkins\workspace\openshift_deploy2
[Pipeline] {
[Pipeline] _OcContextInit
[Pipeline] _OcContextInit
[Pipeline] _OcAction
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.io.IOException: Unable to delete 'C:\Users\myuser\AppData\Local\Temp\ocstdout3566475073744801110.txt'. Tried 3 times (of a maximum of 3) waiting 0.1 sec between attempts.
at hudson.Util.deleteFile(Util.java:257)
at hudson.FilePath$19.invoke(FilePath.java:1453)
at hudson.FilePath$19.invoke(FilePath.java:1450)
at hudson.FilePath.act(FilePath.java:1018)
at hudson.FilePath.act(FilePath.java:996)
at hudson.FilePath.delete(FilePath.java:1450)
at com.openshift.jenkins.plugins.pipeline.OcAction$Execution.run(OcAction.java:222)
at com.openshift.jenkins.plugins.pipeline.OcAction$Execution.run(OcAction.java:119)
at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1$1.call(AbstractSynchronousNonBlockingStepExecution.java:47)
at hudson.security.ACL.impersonate(ACL.java:213)
at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousNonBlockingStepExecution$1.run(AbstractSynchronousNonBlockingStepExecution.java:44)
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:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.nio.file.FileSystemException: C:\Users\myuser\AppData\Local\Temp\ocstdout3566475073744801110.txt: The process cannot access the file because it is being used by another process.

at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
at sun.nio.fs.AbstractFileSystemProvider.deleteIfExists(AbstractFileSystemProvider.java:108)
at java.nio.file.Files.deleteIfExists(Files.java:1165)
at hudson.Util.tryOnceDeleteFile(Util.java:296)
at hudson.Util.deleteFile(Util.java:252)
... 15 more
Finished: FAILURE

@MarkRx this would be the first ever run on Windows, so thanks for that :) . As the Windows user running Jenkins, can you try to delete this file from a command console? This exception is either a simple permissions issue or a file locking issue. Your help would be invaluable in directing my investigation.

I am only able to delete the file after shutting down Jenkins. ProcExplorer shows that the jenkins process is holding on to the file. I don't think it would be a permissions issue since C:\Users\myuser\AppData\Local\Temp\ is the standard Windows temp dir.

Perfect, thank you. I'll see if I can get a Windows environment running.

If you want to try to get further and don't mind the temporary files that will be left behind, removing these lines should be functionally harmless:
https://github.com/jupierce/openshift-jenkins-pipeline-dsl/blob/master/src/main/java/com/openshift/jenkins/plugins/pipeline/OcAction.java#L222-L223

There are input streams that are never closed. Windows is not as forgiving as linux is with file handles.

Example:
byte[] newOutput = IOUtils.toByteArray( stdoutTmp.readFromOffset( stdOut.size() ) );

This can be fixed by closing the input stream when done with it:

byte[] newOutput;
try (InputStream is = stdoutTmp.readFromOffset( stdOut.size() )) {
    newOutput = IOUtils.toByteArray( is );
}

Looks like OcAction and OcWatch have this issue.

Fix pushed. @MarkRx I owe you a beer.

You missed one :)

stdErr.write( IOUtils.toByteArray( stderrTmp.read() ) );

Amended. PTAL.

That fixed it. Thanks!