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

Artifact saving should follow symlink and save the target, optionnally with the symlink name.

    • Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • Jenkins 2.222.3
      Linux OS

      When trying to save some generated files as artifacts , I can easily list the agnostic symlinks created (in my case, by bitbake), and give this list to the artifact step, while the target files have some changing parts depending on the build date or environment; or anything else.
      But the target files are not saved. So, I need to add some extra code, in order to get each target file from each symlink in order to forge the list of files that will be saved.

      It would be very user-friendly to have two options :

      • Follow symlink (and save only target, i.e. file with real content)
      • Name saved files with the symlink name rather than the target name

      And I think that the first option should be set to true as default value, as it is not really interesting to save a symlink alone !

      By the way, the artifact saving behavior should be to follow symlink. And the option should be to save either both symlink and target or target only.

          [JENKINS-62495] Artifact saving should follow symlink and save the target, optionnally with the symlink name.

          jlpinardon added a comment - - edited

          By the way, it would be interesting to have a workaround to help in such a case, specifically when targets cannot be selected through a globbing pattern . I'd like to avoid copying the actual files before saving them.
          I tried a workaround with Java method readSymbolicLink(), but without success

          @NonCPS
           def getRealFileName(String myfileName) {
           myFileName=new File(myfileName)
           Path mypathFile=Paths.get(myfileName)
           println "1-Searching for ${myfileName} real file name with ${mypathFile}"
           String realFileName=Files.readSymbolicLink(Paths.get(myFileName.getAbsolutePath())).toString()
           //String realFileName=pathFile.toRealPath().toString()
           println "2-${myfileName} real file name is " + realFileName
           return realFileName
          }
          

          But, even when giving the exact absolute path of the symbolic link, I get an error message saying that the file does not exist. Which makes me think that there is an additional problem.
          The stack trace looks like :

           00:00:08.273 java.nio.file.NoSuchFileException: /home/jenkins/workspace/jobDev/test/symlinkFile
           00:00:08.273 at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
           00:00:08.273 at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
           00:00:08.273 at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
           00:00:08.273 at sun.nio.fs.UnixFileSystemProvider.readSymbolicLink(UnixFileSystemProvider.java:496)
           00:00:08.273 at java.nio.file.Files.readSymbolicLink(Files.java:1432)
           00:00:08.273 at java_nio_file_Files$readSymbolicLink.callStatic(Unknown Source)
           00:00:08.273 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)
           ...
          00:00:08.273  	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)
          00:00:08.273  	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194)
          **00:00:08.273  	at WorkflowScript.getRealFileName(WorkflowScript:91)**
          00:00:08.273  	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          ...
           00:00:08.273 at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:157)
           00:00:08.273 at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:161)
           00:00:08.273 at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:165)
           00:00:08.273 at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:130)
           00:00:08.273 at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
          *00:00:08.273 at WorkflowScript.run(WorkflowScript:64)*
          

          ... etc ...

          Line 91 is the call to the Java method getRealFileName within the function given above, and line 64 is where this function is called.

          jlpinardon added a comment - - edited By the way, it would be interesting to have a workaround to help in such a case, specifically when targets cannot be selected through a globbing pattern . I'd like to avoid copying the actual files before saving them. I tried a workaround with Java method readSymbolicLink(), but without success @NonCPS def getRealFileName( String myfileName) { myFileName= new File(myfileName) Path mypathFile=Paths.get(myfileName) println "1-Searching for ${myfileName} real file name with ${mypathFile}" String realFileName=Files.readSymbolicLink(Paths.get(myFileName.getAbsolutePath())).toString() // String realFileName=pathFile.toRealPath().toString() println "2-${myfileName} real file name is " + realFileName return realFileName } But, even when giving the exact absolute path of the symbolic link, I get an error message saying that the file does not exist. Which makes me think that there is an additional problem. The stack trace looks like : 00:00:08.273 java.nio.file.NoSuchFileException: /home/jenkins/workspace/jobDev/test/symlinkFile 00:00:08.273 at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86) 00:00:08.273 at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) 00:00:08.273 at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) 00:00:08.273 at sun.nio.fs.UnixFileSystemProvider.readSymbolicLink(UnixFileSystemProvider.java:496) 00:00:08.273 at java.nio.file.Files.readSymbolicLink(Files.java:1432) 00:00:08.273 at java_nio_file_Files$readSymbolicLink.callStatic(Unknown Source) 00:00:08.273 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56) ... 00:00:08.273 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56) 00:00:08.273 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194) **00:00:08.273 at WorkflowScript.getRealFileName(WorkflowScript:91)** 00:00:08.273 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ... 00:00:08.273 at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:157) 00:00:08.273 at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:161) 00:00:08.273 at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:165) 00:00:08.273 at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:130) 00:00:08.273 at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17) *00:00:08.273 at WorkflowScript.run(WorkflowScript:64)* ... etc ... Line 91 is the call to the Java method getRealFileName within the function given above, and line 64 is where this function is called.

            Unassigned Unassigned
            jlpinardon jlpinardon
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: