Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-15331

Workaround Windows unpredictable file locking in Util.deleteContentsRecursive

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Resolved (View Workflow)
    • Priority: Major
    • Resolution: Fixed
    • Component/s: core
    • Labels:
      None
    • Environment:
      Microsoft Windows
    • Similar Issues:

      Description

      Please enhance the hudson.Util.deleteContentsRecursive method to:

      1. delete everything it can
      2. try several times to delete everything
      3. only throw an exception if it can't delete everything (listing everything that it can't delete)

      Reasoning...
      Unlike unix, the Microsoft Windows OS does not allow a file to be deleted if something has that file open. This causes delete operations to fail.
      Furthermore, most installations of Windows have software that monitors the filesystem for activity and then inspects the contents of recently added/removed files (which means that it'll lock them, albeit temporarily), e.g. the Windows Search service & anti-virus software to name but two (but Windows Vista & Windows 7 seem to have additional complications)

      This means that builds which rely on cleaning a workspace before they start will sometimes fail (claiming that they couldn't delete everything because a file was locked), resulting in a build failing with the following output:

      Started by an SCM change
      Building remotely on jenkinsslave27 in workspace C:\hudsonSlave\workspace\MyProject
      Purging workspace...
      hudson.util.IOException2: remote file operation failed: C:\hudsonSlave\workspace\MyProject at hudson.remoting.Channel@6f0564d7:jenkinsslave27
      	at hudson.FilePath.act(FilePath.java:835)
      	at hudson.FilePath.act(FilePath.java:821)
      	at hudson.plugins.accurev.AccurevSCM.checkout(AccurevSCM.java:331)
      	at hudson.model.AbstractProject.checkout(AbstractProject.java:1218)
      	at hudson.model.AbstractBuild$AbstractRunner.checkout(AbstractBuild.java:586)
      	at hudson.model.AbstractBuild$AbstractRunner.run(AbstractBuild.java:475)
      	at hudson.model.Run.run(Run.java:1434)
      	at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:46)
      	at hudson.model.ResourceController.execute(ResourceController.java:88)
      	at hudson.model.Executor.run(Executor.java:239)
      Caused by: java.io.IOException: Unable to delete C:\hudsonSlave\workspace\MyProject\...\src\...\foo - files in dir: [C:\hudsonSlave\workspace\MyProject\...\src\...\foo\bar]
      	at hudson.Util.deleteFile(Util.java:236)
      	at hudson.Util.deleteRecursive(Util.java:287)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.Util.deleteRecursive(Util.java:278)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.Util.deleteRecursive(Util.java:278)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.Util.deleteRecursive(Util.java:278)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.Util.deleteRecursive(Util.java:278)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.Util.deleteRecursive(Util.java:278)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.Util.deleteRecursive(Util.java:278)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.Util.deleteRecursive(Util.java:278)
      	at hudson.Util.deleteContentsRecursive(Util.java:198)
      	at hudson.plugins.accurev.PurgeWorkspaceContents.invoke(PurgeWorkspaceContents.java:28)
      	at hudson.plugins.accurev.PurgeWorkspaceContents.invoke(PurgeWorkspaceContents.java:11)
      	at hudson.FilePath$FileCallableWrapper.call(FilePath.java:2161)
      	at hudson.remoting.UserRequest.perform(UserRequest.java:118)
      	at hudson.remoting.UserRequest.perform(UserRequest.java:48)
      	at hudson.remoting.Request$2.run(Request.java:287)
      	at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
      	at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
      	at java.util.concurrent.FutureTask.run(Unknown Source)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      	at hudson.remoting.Engine$1$1.run(Engine.java:60)
      	at java.lang.Thread.run(Unknown Source)
      

      What's needed is a retry mechanism. i.e. the equivalent of using Ant's <retry><delete file="foo"/></retry>, but with a (small) delay between attempts (and maybe a call to the garbage collector, just in case the process holding the file open is the build slave process itself).

        Attachments

          Issue Links

            Activity

            Hide
            jorgziegler Jörg Ziegler added a comment -

            Daniel Beck thanks for the quick replies. Is there any field that would need updating in this issue so that it will be included in a .4?

            Show
            jorgziegler Jörg Ziegler added a comment - Daniel Beck thanks for the quick replies. Is there any field that would need updating in this issue so that it will be included in a .4?
            Hide
            oleg_nenashev Oleg Nenashev added a comment -

            Actually we still can merge it to .3 if Oliver Gondža agrees. But I'm not so happy about it since RC is under testing now.
            Regarding .4, it will unlikely happen according to the current release model. Needs a wide discussion in the developer list.

            BR, Oleg

            Show
            oleg_nenashev Oleg Nenashev added a comment - Actually we still can merge it to .3 if Oliver Gondža agrees. But I'm not so happy about it since RC is under testing now. Regarding .4, it will unlikely happen according to the current release model. Needs a wide discussion in the developer list. BR, Oleg
            Hide
            danielbeck Daniel Beck added a comment -

            We don't do .4's, except when we mess up so badly there's no way around it, but this doesn't qualify.

            Show
            danielbeck Daniel Beck added a comment - We don't do .4's, except when we mess up so badly there's no way around it , but this doesn't qualify.
            Hide
            olivergondza Oliver Gondža added a comment -

            I decided not to squeeze this into .3 (last in its line) for stability's sake. We need to be extra careful as we do not do much testing on windows, unfortunately.

            Show
            olivergondza Oliver Gondža added a comment - I decided not to squeeze this into .3 (last in its line) for stability's sake. We need to be extra careful as we do not do much testing on windows, unfortunately.
            Hide
            olivergondza Oliver Gondža added a comment -

            Consumed by 2.7.X line so need to backport.

            Show
            olivergondza Oliver Gondža added a comment - Consumed by 2.7.X line so need to backport.

              People

              • Assignee:
                Unassigned
                Reporter:
                pjdarton pjdarton
              • Votes:
                28 Vote for this issue
                Watchers:
                37 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: