Search code examples
groovykubectljenkins-groovyjenkins-declarative-pipeline

MultipleCompilationErrorsException in groovy while executing kubectl to find java process id from a pod


This is my line from declarative pipeline in groovy to fetch java process ID from a k8s pod:

def jpsid = "${kubectl exec -i "${pod}"  -n *<some_namespace>* -- jps | awk '{ print "${1}"}'}"

i expect a 2 digit value to be mapped to jpsid.

Could someone suggest how to overcome this issue.

Error below i got is:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 33: expecting '}', found 'jps' @ line 33, column 95.
    -n *<some_namespace>* -- jps | awk 
                                 ^

1 error

  at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:309)
  at org.codehaus.groovy.control.ErrorCollector.addFatalError(ErrorCollector.java:149)
  at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:119)
  at org.codehaus.groovy.control.ErrorCollector.addError(ErrorCollector.java:131)
  at org.codehaus.groovy.control.SourceUnit.addError(SourceUnit.java:349)
  at org.codehaus.groovy.antlr.AntlrParserPlugin.transformCSTIntoAST(AntlrParserPlugin.java:225)
  at org.codehaus.groovy.antlr.AntlrParserPlugin.parseCST(AntlrParserPlugin.java:191)
  at org.codehaus.groovy.control.SourceUnit.parse(SourceUnit.java:233)
  at org.codehaus.groovy.control.CompilationUnit$1.call(CompilationUnit.java:189)
  at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:966)
  at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:626)
  at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:602)
  at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:579)
  at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:323)
  at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:293)
  at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox$Scope.parse(GroovySandbox.java:163)
  at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:190)
  at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:175)
  at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:568)
  at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:518)
  at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:336)
  at hudson.model.ResourceController.execute(ResourceController.java:101)
  at hudson.model.Executor.run(Executor.java:442)
[withMaven] downstreamPipelineTriggerRunListener - Failure to introspect build steps: java.io.IOException: k8s_ops #43 did not yet start
[withMaven] downstreamPipelineTriggerRunListener - Failure to introspect build steps: java.io.IOException: k8s_ops #43 did not yet start
Finished: FAILURE

Tried extracting java process id from a k8s pod using a declarative pipeline via jenkins. expected a 2 digit no assigned to variable "jpsid"


Solution

  • The given line would not work, for a start, it lacks a lot of escaping and string would not execute on their own. It is programmatically unclear where the string starts and ends. I would have expected something more like the following pseudo-code:

    def jpsCommand = "kubectl exec -i \"${pod}\"  -n *<some_namespace>* -- jps | awk '{ print \$1 }'}"
    def jpsId = sh(script: jpsCommand, returnStdout: true).trim()
    

    PS: Warning with pipes: Jenkins has a "strange" way it handles pipe subshells; see something like this stackoverflow post to get an idea of the weirdness. It might be better to run commands with pipes in the following structure: sh(script: "/bin/bash -c '...'"). It would require some additional escaping. Psuedo-code example:

    def jpsCommand = "kubectl exec -i \"${pod}\"  -n *<some_namespace>* -- /bin/bash -c 'jps | awk \'{ print \$1 }\''"
    def jpsId = sh(script: jpsCommand, returnStdout: true).trim()