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

Kubernetes plugin creates workspace with linux-style root path on a Windows node

      Setup

      • Jenkins 2.303.3
      • P4 Plugin 1.11.6

      Where Jenkins master is running on Linux

      Running slaves on a Kubernetes cluster (configured as Cloud) as Pod Templates

       

      Repro Steps

       

      1. Create a pod template that will execute on a Windows Kubernetes node
      2. Create a pipeline that uses uses the pod template as its agent
      3. Attempt to checkout a p4 stream on the a container of the windows pod (it can be the jnlp container)

      Expectations

      The stream should be checked out at the current location

      Observations

      P4 fails to checkout with the following error:

       

      ERROR: P4: Task Exception: hudson.AbortException: P4JAVA: Error(s):
      Path 'C:/home/jenkins/agent/workspace/gpetit/gpetit-windows/...' is not under client's root '/home/jenkins/agent/workspace/gpetit/gpetit-windows'. 
      

       

      Additional Details

      The the pod template looks like this:
       

      apiVersion: "v1"
      kind: "Pod"
      metadata:  
        labels:
          jenkins/label: "windows-architecture-base"
      spec:
        containers:
        - image: "jenkins/inbound-agent:windowsservercore-ltsc2019"
          name: "jnlp"
        nodeSelector:
           kubernetes.io/os: "windows"
      

       

      The pipeline:

      pipeline {
          agent { label 'windows-architecture-base' }
      
          stages {
              stage('Checkout') {
                 steps {
                     script {
                          powershell "Get-ChildItem env:"
                          checkout perforce(
                              credential: 'gpetit-p4',
                              populate: autoClean(delete: true, modtime: false, parallel: [enable: true, minbytes: '1024', minfiles: '1', threads: '4'], pin: '', quiet: true, replace: true, tidy: false),
                              workspace: streamSpec(charset: 'none', format: 'jenkins-${NODE_NAME}-${JOB_NAME}-${EXECUTOR_NUMBER}', pinHost: false, streamName: '//depot/stream-main')
                              )
                      }
                  }
              }
          }
      }
      

      When printing environment variables, noteworthy is that the WORKSPACE is set as a linux path:

      WORKSPACE       /home/jenkins/agent/workspace/gpetit/gpetit-windows                           
      WORKSPACE_TMP   /home/jenkins/agent/workspace/gpetit/gpetit-windows@tmp
      

          [JENKINS-67156] Kubernetes plugin creates workspace with linux-style root path on a Windows node

          Karl Wirth added a comment -

          gpetit - Thanks for highlighting this. I'll do some testing here and get back to you.

          Karl Wirth added a comment - gpetit - Thanks for highlighting this. I'll do some testing here and get back to you.

          Karl Wirth added a comment -

          Hi gpetit ,

          I've run this without Kubernates and it works as expected:

          WORKSPACE                      E:\filestore\Jenkins\Windows10Swarm202\workspace\Windows10PipelineStream                
          WORKSPACE_TMP                  E:\filestore\Jenkins\Windows10Swarm202\workspace\Windows10PipelineStream@tmp  
          

          and my client root is:

          ... p4 client -i +
          ...   View: -
          ...   Stream: //streams/main
          ...   Root: E:\filestore\Jenkins\Windows10Swarm202\workspace\Windows10PipelineStream
          

          The workspace is the area on disk the Jenkins slave has chosen to run the job. I beleive the WORKSPACE variable is coming from the definition of the Jenkins slave not P4Jenkins so I think this is a problem with the slave definition on the Kubernates side. For example if this was a manually defined node workspace comes from the name of the job and:

          I'm not familiar enough with Kubernates to know where you need to look to change this to be a Windows path.

          Does the full console log give any indication of where Jenkins is trying to run the Jenkinsfile?

          Karl Wirth added a comment - Hi gpetit , I've run this without Kubernates and it works as expected: WORKSPACE E:\filestore\Jenkins\Windows10Swarm202\workspace\Windows10PipelineStream WORKSPACE_TMP E:\filestore\Jenkins\Windows10Swarm202\workspace\Windows10PipelineStream@tmp and my client root is: ... p4 client -i + ... View: - ... Stream: //streams/main ... Root: E:\filestore\Jenkins\Windows10Swarm202\workspace\Windows10PipelineStream The workspace is the area on disk the Jenkins slave has chosen to run the job. I beleive the WORKSPACE variable is coming from the definition of the Jenkins slave not P4Jenkins so I think this is a problem with the slave definition on the Kubernates side. For example if this was a manually defined node workspace comes from the name of the job and: I'm not familiar enough with Kubernates to know where you need to look to change this to be a Windows path. Does the full console log give any indication of where Jenkins is trying to run the Jenkinsfile?

          Karl Wirth added a comment -

          Hi gpetit - How's the investigation going? Did you find anything on the Kubernates side?

          Karl Wirth added a comment - Hi gpetit - How's the investigation going? Did you find anything on the Kubernates side?

          Hi,

          I've been assisting with this issue on our side. I believe it actually is an issue with the Kubernetes plugin not setting the WORKSPACE variable properly.

          We have had some success with a workaround by skipping the default checkout and specifying a workspace using ws() after converting the present WORKSPACE variable into a Windows path.

          It's not ideal, so we still believe it's a bug that should be fixed. It does seem, however, that it's not an issue with the P4 plugin after all (since it simply uses the WORKSPACE variable) and is more likely a bug with the kubernetes plugin.

          Matthew Brunton added a comment - Hi, I've been assisting with this issue on our side. I believe it actually is an issue with the Kubernetes plugin not setting the WORKSPACE variable properly. We have had some success with a workaround by skipping the default checkout and specifying a workspace using ws() after converting the present WORKSPACE variable into a Windows path. It's not ideal, so we still believe it's a bug that should be fixed. It does seem, however, that it's not an issue with the P4 plugin after all (since it simply uses the WORKSPACE variable) and is more likely a bug with the kubernetes plugin.

          Karl Wirth added a comment -

          Hi mbrunton27 ,

          Thanks for letting us know. If there is anything we can do on the P4-Plugin side just reply to this thread or drop me an email at support@perforce.com.

          Karl Wirth added a comment - Hi mbrunton27 , Thanks for letting us know. If there is anything we can do on the P4-Plugin side just reply to this thread or drop me an email at support@perforce.com.

          Gaspard Petit added a comment -

          Confirming this is a kubernetes issue, not a perforce issue. We ran into the same problem against the docker-plugin:

          On a windows node, `docker.withRegistry / push` will also fail unless wrapped around with a `ws` pointing to a windows-converted path. Once we "fix" the workspace, it works.

          For others who will run into similar issues, our workaround looks like this:

           

          def linuxPathToWindows(path)
          {
              return "C:${path.replace('/', '\\')}"
          }
          
          pipeline {
            options {skipDefaultCheckout()}
          
            stages {
              stage('Configure') { steps { script {
                FIXED_WORKSPACE = linuxPathToWindows(env.WORKSPACE)
              } } }
          
              stage('Build') { steps { 
                ws(FIXED_WORKSPACE) {
                  script {
                    // will work now that we fixed the workspace with 'ws'
                    checkout scm
          
                    docker.withRegistry('repo', 'repouser') {
                      // will work now that we fixed the workspace
            } } } } } }
          }
          

           

          Gaspard Petit added a comment - Confirming this is a kubernetes issue, not a perforce issue. We ran into the same problem against the docker-plugin: On a windows node, `docker.withRegistry / push` will also fail unless wrapped around with a `ws` pointing to a windows-converted path. Once we "fix" the workspace, it works. For others who will run into similar issues, our workaround looks like this:   def linuxPathToWindows(path) { return "C:${path.replace( '/' , '\\' )}" } pipeline { options {skipDefaultCheckout()} stages { stage( 'Configure' ) { steps { script { FIXED_WORKSPACE = linuxPathToWindows(env.WORKSPACE) } } } stage( 'Build' ) { steps { ws(FIXED_WORKSPACE) { script { // will work now that we fixed the workspace with 'ws' checkout scm docker.withRegistry( 'repo' , 'repouser' ) { // will work now that we fixed the workspace } } } } } } }  

            Unassigned Unassigned
            gpetit Gaspard Petit
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: