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

Wipe out repository & force clone ignore's Windows directory junctions

XMLWordPrintable

      During building, I have a custom build script that does the following:
      1. Downloads dependency code to the machine in a specific location.
      2. In the Jenkins workspace directory, it creates a pointer that specific location:
      – On Windows, it uses directory junctions (mklink /J <dest> <src>). I use directory junctions because Symlinks are disabled by default in my environment.
      – On Linux, it uses symlinks (ln -s <src> <dest>)
      3. Builds the code

      When this project is built again, I have the "Wipe out repository & force clone" option set to make sure that we get a clean clone for GIT. This code calls down to hudson.FilePath.deleteContents(), which calls deleteContentsRecursive(), which calls deleteRecursive(). In here, we have
      if (!isSymlink(dir))
      deleteContensRecursive(dir)
      try

      { deleteFile(deleting(dir)) }

      ....

      In this call to isSymlink(), it is not determining that my Windows directory junction is really just a symlink. So, it is proceeding down the junction and deleting the machine cache contents, which is not wanted. On Linux, it properly detects the symlink, and only deletes the symlink.

      It looks like the change that causes this was introduced in ed748d4 – Try to use NIO.2 for Java 7. It was subsequently revised to put this code into it's own function (b6f924d) Unfortunately, the Java 7 isSymbolicLink function does not count a Windows directory junction as a symlink either. You have to go to BasicFileAttributes and call isOther to along with isSymbolicLink to determine if the path in question is a Windows reparse point (Windows directory junctions are reparse poitns).

      This change of using Java 7 (if available) was done right before a function designed to check on Windows for either a Windows symbolic link (CreateSymbolicLink) or Directory junction (parse point). That function is Kernel32Utils.isJunctionOrSymlink(file). If this call is moved before the call to the isSymlinkJava7, then it will properly detect the directory junction and not recursively remove it's contents. It will just remove the junction.

      I have created a Pull-Request that implements this change (https://github.com/jenkinsci/jenkins/pull/1787).

            Unassigned Unassigned
            dbroady1 Darin Broady
            Votes:
            2 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: