[JIRA] (JENKINS-58620) MPL shared library logic execution caused CPS mismatch warning

2 visualizzazioni
Passa al primo messaggio da leggere

sparshev@griddynamics.com (JIRA)

da leggere,
23 lug 2019, 16:23:0223/07/19
a jenkinsc...@googlegroups.com
Sergei Parshev created an issue
 
Jenkins / Bug JENKINS-58620
MPL shared library logic execution caused CPS mismatch warning
Issue Type: Bug Bug
Assignee: Unassigned
Components: workflow-cps-plugin
Created: 2019-07-23 20:22
Environment: Jenkins 2.176.2 with minimal plugins to execute pipeline shared libraries (git, pipeline, pipeline shared libs).
Labels: pipeline cps groovy workflow-cps mpl
Priority: Minor Minor
Reporter: Sergei Parshev

We found a change that prints an annoying warning about the CPS mismatch during running the MPL module: https://github.com/griddynamics/mpl/issues/31

Running on Jenkins in /var/jenkins_home/workspace/mpl-master
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Checkout)
[Pipeline] fileExists
expected to call org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.evaluate but wound up catching Checkout.run; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/

We're not quite sure how to fix that in the library, but realized that the issue is related to the change JENKINS-31314 introduced in workflow-cps-2.71.

Reproduce is quite simple - just need to install the minimal latest jenkins, add required git & shared lib plugins, attach mpl library from github and create a simple jenkins job to build the mpl. It will fail (no Maven 3 tool) - but will show the issue during each module start.

Who could help with determining the actual cause and how to fix that?

Add Comment Add Comment
 
This message was sent by Atlassian Jira (v7.11.2#711002-sha1:fdc329d)

sparshev@griddynamics.com (JIRA)

da leggere,
3 ago 2019, 14:04:0203/08/19
a jenkinsc...@googlegroups.com
Sergei Parshev commented on Bug JENKINS-58620
 
Re: MPL shared library logic execution caused CPS mismatch warning

Jesse Glick, Devin Nusbaum - could you please check? Probably jenkins shouldn't show such messages in the job log?

sparshev@griddynamics.com (JIRA)

da leggere,
5 ago 2019, 21:30:0205/08/19
a jenkinsc...@googlegroups.com

jglick@cloudbees.com (JIRA)

da leggere,
6 ago 2019, 13:25:0206/08/19
a jenkinsc...@googlegroups.com
Jesse Glick commented on Bug JENKINS-58620
 
Re: MPL shared library logic execution caused CPS mismatch warning

Is there a self-contained minimal test case to reproduce the issue? Preferably just a single Jenkinsfile with all inessential lines removed.

sparshev@griddynamics.com (JIRA)

da leggere,
6 ago 2019, 13:42:0206/08/19
a jenkinsc...@googlegroups.com

sparshev@griddynamics.com (JIRA)

da leggere,
6 ago 2019, 14:00:0206/08/19
a jenkinsc...@googlegroups.com
Sergei Parshev commented on Bug JENKINS-58620
 
Re: MPL shared library logic execution caused CPS mismatch warning

Hi Jesse Glick,

Unfortunately it's impossible to prepare just a Jenkinsfile - MPL is a shared library. We already tracked down the issue - and found, that the message are produced during the module run in Helper.groovy:

  static void runModule(String src, String path, Map vars = [:]) {
    getShell(vars).evaluate(src, path)
  }

If we using the minimal Jeninsfile from the MPL repo, the call tracepath to the first `Checkout` module "expected to call" message looks like this:

This issue is not critical, but prints the verbose information that looks weird and not helpful for the end users...

jglick@cloudbees.com (JIRA)

da leggere,
6 ago 2019, 14:04:0206/08/19
a jenkinsc...@googlegroups.com

MPL is a shared library

I understand that, but I suspect that the trigger condition for the bug could be narrowed down to something which could be written in a single short script, perhaps using some local function definitions or whatever. Even if it is actually impossible to reproduce without a library, then the minimal self-contained test case would be a minimal library (probably one source file with a few lines) and an accompanying Jenkinsfile.

sparshev@griddynamics.com (JIRA)

da leggere,
6 ago 2019, 14:30:0206/08/19
a jenkinsc...@googlegroups.com

Ok, I think I can prepare a simple vars-only shared lib with such call.

sparshev@griddynamics.com (JIRA)

da leggere,
6 ago 2019, 14:56:0506/08/19
a jenkinsc...@googlegroups.com

What I've done:

  1. Started 2.176.2 jenkins with the next plugins.txt:
    • git
    • workflow-aggregator
  2. Added shared library "test" with the local repo in /var/jenkins_home/test_shared_lib and "master" version by default
  3. Init git repo /var/jenkins_home/test_shared_lib and created commit with the next content:
    • vars/executeGroovyScript.groovy
      import org.jenkinsci.plugins.workflow.cps.CpsGroovyShellFactory
      import org.jenkinsci.plugins.workflow.cps.CpsThread
      
      def call(String src, String path, Map vars = [:]) {
        getShell(vars).evaluate(src, path)
      }
      
      def getShell(Map vars = [:]) {
        def ex = CpsThread.current().getExecution()
        def shell = new CpsGroovyShellFactory(ex).withParent(ex.getShell()).build()
        vars.each { key, val -> shell.setVariable(key, val) }
        shell
      }
      
  4. Created test job with pipeline script:
    @Library('test') _
    
    executeGroovyScript('echo "hello world"', 'Module.groovy')
    

And the job execution result is:

Started by user unknown or anonymous
Running in Durability level: MAX_SURVIVABILITY
Loading library test@master
Attempting to resolve master from remote references...
 > git --version # timeout=10
 > git ls-remote -h /var/jenkins_home/test_shared_lib # timeout=10
Found match: refs/heads/master revision a8aa6eeacb2a84f533d33ca4bd6cb4851aa95dd5
No credentials specified
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url /var/jenkins_home/test_shared_lib # timeout=10
Fetching without tags
Fetching upstream changes from /var/jenkins_home/test_shared_lib
 > git --version # timeout=10
 > git fetch --no-tags --force --progress /var/jenkins_home/test_shared_lib +refs/heads/*:refs/remotes/origin/*
Checking out Revision a8aa6eeacb2a84f533d33ca4bd6cb4851aa95dd5 (master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f a8aa6eeacb2a84f533d33ca4bd6cb4851aa95dd5
Commit message: "Init"
 > git rev-list --no-walk b3d7243e87528f2a8971101d2b93c8eeba904466 # timeout=10
[Pipeline] Start of Pipeline
expected to call org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.evaluate but wound up catching Module.run; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
[Pipeline] echo
hello world
[Pipeline] End of Pipeline
Finished: SUCCESS

jglick@cloudbees.com (JIRA)

da leggere,
6 ago 2019, 15:00:0306/08/19
a jenkinsc...@googlegroups.com

Explicit use of org.jenkinsci.plugins.workflow.cps.* implementation classes cannot be considered supported. What exactly is this code attempting to accomplish?

sparshev@griddynamics.com (JIRA)

da leggere,
6 ago 2019, 15:22:0206/08/19
a jenkinsc...@googlegroups.com

This logic is executing content `src` in sandbox as the original pipeline - MPL purpose is to separate the pipeline logic into modules. So this function is basic for the library - it creates another CPS shell with only variables provided into the script.

jglick@cloudbees.com (JIRA)

da leggere,
6 ago 2019, 15:56:0206/08/19
a jenkinsc...@googlegroups.com

Normally this sort of thing would be handled with simple closures etc., not evaluate. Since this is a nonstandard usage, I would consider the priority low.

There was an effort (since backed out) to offer an SPI by which plugins with exotic workflow-cps usages could suppress the warnings for their special call patterns, but that would be of no use to you anyway.

jglick@cloudbees.com (JIRA)

da leggere,
6 ago 2019, 16:00:0306/08/19
a jenkinsc...@googlegroups.com

I suspect this issue has nothing to do with libraries per se and could be reproduced in a self-contained Jenkinsfile. Maybe

def ex = CpsThread.current().execution
new CpsGroovyShellFactory(ex).withParent(ex.shell).build().evaluate('echo "OK"', 'X.groovy')

or maybe even just

evaluate('echo "OK"', 'X.groovy')

since I think existing tests only cover the overload taking only a single String parameter.

If so, it is a bug somewhere in the way evaluate is being handled, and is probably very easy to fix in groovy-cps.

sparshev@griddynamics.com (JIRA)

da leggere,
6 ago 2019, 17:28:0306/08/19
a jenkinsc...@googlegroups.com

Yeah, `evaluate()` is almost the same - but the reason to use a separated CpsGroovyShell - is to enclave the script and to bind a special variables (`CFG` from the MPLModule.groovy).

Yeah, it's low priority, but there is a way to move such messages into the jenkins master log for example? I think it's not a useful message for the ones, who actually want to see the build log...

sparshev@griddynamics.com (JIRA)

da leggere,
6 ago 2019, 17:34:0206/08/19
a jenkinsc...@googlegroups.com
Sergei Parshev edited a comment on Bug JENKINS-58620
Yeah, Probably you can use CpsThread or CpsGroovyShellFactory without sandbox flag - but we're worrying about the security - and don't allow modules/scripts to be used with the shared library permissions. We preparing pipelines in the shared library (because pipelines are common) and executing their logic (stored in modules) again in the sandbox with help of the CpsGroovyShell.

Just
`evaluate()` is almost the same - but the reason to use a separated CpsGroovyShell - is to enclave the script and to bind a special variables (`CFG` from the MPLModule.groovy).


Yeah, it's low priority, but there is a way to move such messages into the jenkins master log for example? I think it's not a useful message for the ones, who actually want to see the build log...


What do you think about the solutions? Maybe I can help with the implementation?

jglick@cloudbees.com (JIRA)

da leggere,
7 ago 2019, 15:17:0207/08/19
a jenkinsc...@googlegroups.com

there is a way to move such messages into the jenkins master log

No, this would hide the critical diagnostic information from the people writing Pipelines who are normally responsible for making mistakes here.

The first step is to have a PR up with an addition to the existing @Ignore’d test case demonstrating the problem using the shortest possible script, possibly something like one of the above examples. In that case, a fix in groovy-cps is likely possible.

sparshev@griddynamics.com (JIRA)

da leggere,
9 ago 2019, 17:26:0209/08/19
a jenkinsc...@googlegroups.com

Hi Jesse Glick, ok I got it - if it's not about security, but about a simple example to show that we need an exception in the warning logic: I tested with turned off sandbox - found a minimal implementation to show the issue:

  • Jenkinsfile:
    org.jenkinsci.plugins.workflow.cps.CpsThread.current().getExecution().getShell().evaluate('echo "OK"', 'X.groovy')
    
  • Output:
    Started by user unknown or anonymous
    Running in Durability level: MAX_SURVIVABILITY
    [Pipeline] Start of Pipeline
    expected to call org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.evaluate but wound up catching X.run; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
    [Pipeline] echo
    OK
    [Pipeline] End of Pipeline
    Finished: SUCCESS
    

sparshev@griddynamics.com (JIRA)

da leggere,
9 ago 2019, 17:51:0209/08/19
a jenkinsc...@googlegroups.com

I think there is two ways to fix the issue:

  1. Prepare modification for evaluate step to be able to execute groovy logic with providing the src path and bindings
  2. Prepare an exception for executing CpsGroovyShell.evaluate https://github.com/cloudbees/groovy-cps/pull/99

Jesse Glick what do you think will be better? Easier for sure prepare an exception hack, but probably that will be appropriate to modify the evaluate step?

Or maybe even prepare `module` step and put such MPL functionality into the Jenkins itself? I'm just not sure that it's a good idea because probably I will need to prepare an additional plugin and I would avoid that and keep minimal requirements for the MPL library.

sparshev@griddynamics.com (JIRA)

da leggere,
9 ago 2019, 18:00:0309/08/19
a jenkinsc...@googlegroups.com
Sergei Parshev edited a comment on Bug JENKINS-58620
I think there is two ways to fix the issue:
# Prepare modification overload for [ evaluate step function|https://github.com/jenkinsci/workflow-cps-plugin/blob/master/src/main/java/org/jenkinsci/plugins/workflow/cps/CpsScript.java#L179] to be able to execute groovy logic with providing the src path and bindings
# Prepare an exception for executing CpsGroovyShell.evaluate https://github.com/cloudbees/groovy-cps/pull/99

[~jglick] what do you think will be better? Easier for sure prepare an exception hack, but probably that will be appropriate to modify the evaluate step?


Or maybe even prepare `module` step and put such MPL functionality into the Jenkins itself? I'm just not sure that it's a good idea because probably I will need to prepare an additional plugin and I would avoid that and keep minimal requirements for the MPL library.
Rispondi a tutti
Rispondi all'autore
Inoltra
0 nuovi messaggi