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

Cannot use custom agent directive in Jenkinsfile

      We are not able to use custom directive for "agent".
      We'd like to create a set of reusable directives, including few of those replacing the default agent directive. The error thrown is:

      org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
      WorkflowScript: 4: Undefined section "nodeAgent" @ line 4, column 5.
             nodeAgent(
             ^
      
      WorkflowScript: 3: Missing required section "agent" @ line 3, column 1.
         pipeline {
         ^
      
      2 errors
      
      	at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
      	at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
      	at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
      	at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
      	at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
      	at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
      	at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
      	at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
      	at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
      	at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.lambda$doParse$0(CpsGroovyShell.java:135)
      	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:136)
      	at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:132)
      	at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:127)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:560)
      	at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:521)
      	at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:320)
      	at hudson.model.ResourceController.execute(ResourceController.java:97)
      	at hudson.model.Executor.run(Executor.java:429)
      Finished: FAILURE
      

      And the Jenkinsfile

      @Library('jenkins-pipelines') _
      
      pipeline {
          nodeAgent(
              version: '10'
          )
          stages {
              stage('Build') {
                  ...
              }     
              stage('Test') {
                  ...
              }
              stage('Publish') {
                  ...
              }
          }
      }
      

      We'd like to run this within a docker container with NodeJS {version}, so for that reason we've decided to create a reusable nodeAgent directive.

      def call(Map<String, String> opts) {
          def spec = new NodeAgentSpec(opts)    
      
          if (!spec.version) {
              throw new RuntimeException('version must be provided')
          }
      
          new node().agent(spec)
      }
      

      and for the node.groovy

      def agent(NodeAgentSpec spec) {
          def cacheFolderPath = '$HOME' + "/.docker-cache/node/${spec.version}"    
          
          sh "mkdir -p ${cacheFolderPath}"
          sh "chmod 777 -R ${cacheFolderPath}"    
          
          agent {
              docker {
                  image "local/nodejs-node-${spec.version}"
                  args "-v ${cacheFolderPath}:/home/node/.cache"
              }
          }
      }
      

      We also need to set custom permissions (chmod 777) for our cache folder, that is being mounted to docker container, so we can avoid running docker container with root privileges.

       

       

          [JENKINS-56605] Cannot use custom agent directive in Jenkinsfile

          David Rajnic created issue -
          David Rajnic made changes -
          Description Original: We are not able to use custom directive for "agent".
          We'd like to create a set of reusable directives, including few of those replacing the default agent directive. The error thrown is:
          {code:java}
          org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
          WorkflowScript: 4: Undefined section "nodeAgent" @ line 4, column 5.
                 nodeAgent(
                 ^

          WorkflowScript: 3: Missing required section "agent" @ line 3, column 1.
             pipeline {
             ^

          2 errors

          at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
          at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
          at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
          at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
          at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
          at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
          at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
          at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
          at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
          at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.lambda$doParse$0(CpsGroovyShell.java:135)
          at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:136)
          at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:132)
          at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:127)
          at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:560)
          at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:521)
          at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:320)
          at hudson.model.ResourceController.execute(ResourceController.java:97)
          at hudson.model.Executor.run(Executor.java:429)
          Finished: FAILURE
          {code}

          And the Jenkinsfile
          {code:java}
          @Library('jenkins-pipelines') _

          pipeline {
              nodeAgent(
                  version: '10'
              )
              stages {
                  stage('Build') {
                      ...
                  }
                  stage('Test') {
                      ...
                  }
                  stage('Publish') {
                      ...
                  }
              }
          }
          {code}

          We'd like to run this within a docker container with NodeJS \{version}, so for that reason we've decided to create a reusable *nodeAgent* directive.


          {code:java}
          def agent(NodeAgentSpec spec) {
              def cacheFolderPath = '$HOME' + "/.docker-cache/node/${spec.version}"
              
              sh "mkdir -p ${cacheFolderPath}"
              sh "chmod 777 -R ${cacheFolderPath}"
              
              agent {
                  docker {
                      image "local/nodejs-node-${spec.version}"
                      args "-v ${cacheFolderPath}:/home/node/.cache"
                  }
              }
          }
          {code}
          We also need to set custom permissions (chmod 777) for our cache folder, that is being mounted to docker container, so we can avoid running docker container with root privileges.

           

           
          New: We are not able to use custom directive for "agent".
           We'd like to create a set of reusable directives, including few of those replacing the default agent directive. The error thrown is:
          {code:java}
          org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
          WorkflowScript: 4: Undefined section "nodeAgent" @ line 4, column 5.
                 nodeAgent(
                 ^

          WorkflowScript: 3: Missing required section "agent" @ line 3, column 1.
             pipeline {
             ^

          2 errors

          at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
          at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
          at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
          at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
          at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
          at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
          at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
          at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
          at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
          at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.lambda$doParse$0(CpsGroovyShell.java:135)
          at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:136)
          at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:132)
          at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:127)
          at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:560)
          at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:521)
          at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:320)
          at hudson.model.ResourceController.execute(ResourceController.java:97)
          at hudson.model.Executor.run(Executor.java:429)
          Finished: FAILURE
          {code}
          And the Jenkinsfile
          {code:java}
          @Library('jenkins-pipelines') _

          pipeline {
              nodeAgent(
                  version: '10'
              )
              stages {
                  stage('Build') {
                      ...
                  }
                  stage('Test') {
                      ...
                  }
                  stage('Publish') {
                      ...
                  }
              }
          }
          {code}
          We'd like to run this within a docker container with NodeJS \{version}, so for that reason we've decided to create a reusable *nodeAgent* directive.


          {code:java}
          def call(Map<String, String> opts) {
              def spec = new NodeAgentSpec(opts)

              if (!spec.version) {
                  throw new RuntimeException('version must be provided')
              }

              new node().agent(spec)
          }
          {code}
          and for the *node.groovy*
          {code:java}
          def agent(NodeAgentSpec spec) {
              def cacheFolderPath = '$HOME' + "/.docker-cache/node/${spec.version}"
              
              sh "mkdir -p ${cacheFolderPath}"
              sh "chmod 777 -R ${cacheFolderPath}"
              
              agent {
                  docker {
                      image "local/nodejs-node-${spec.version}"
                      args "-v ${cacheFolderPath}:/home/node/.cache"
                  }
              }
          }
          {code}
          We also need to set custom permissions (chmod 777) for our cache folder, that is being mounted to docker container, so we can avoid running docker container with root privileges.

           

           
          Oleg Nenashev made changes -
          Component/s New: pipeline-model-definition-plugin [ 21706 ]
          Oleg Nenashev made changes -
          Assignee New: Andrew Bayer [ abayer ]

          Andrew Bayer added a comment -

          Andrew Bayer added a comment - I think what you should be doing is implementing an agent, like https://github.com/jenkinsci/kubernetes-plugin/blob/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgent.java .

          David Rajnic added a comment -

          abayer so there is no other way I can just simply wrap existing agent.docker directive into custom directive? The solution you've proposed seems quite a big for something that is already implemented in docker-plugin

          David Rajnic added a comment - abayer so there is no other way I can just simply wrap existing agent.docker directive into custom directive? The solution you've proposed seems quite a big for something that is already implemented in  docker-plugin
          Andrew Bayer made changes -
          Assignee Original: Andrew Bayer [ abayer ]

            Unassigned Unassigned
            nesquik4 David Rajnic
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: