1

I have an odd issue. I am working on a Jenkins CasC pipeline to auto populate jobs at startup. Everything was fine, until I started adding parameters. Running the added the below code from a job fails for the 1st time, then when I rerun subsequently it works. A forum I found stated that running the Groovy code needs to register the param and that why stuff works from second build onwards. It also stated that loading via CasC this first time error is not an issue. Loading via CasC however produces the below error. Note the exact code works fine when when saved from the code and having that 1st time error.

Error:

hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: app for class: WorkflowScript
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:66)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:471)
    at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.getProperty(DefaultInvoker.java:39)
    at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:20)
    at WorkflowScript.run(WorkflowScript:19)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.delegateAndExecute(ModelInterpreter.groovy:137)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.executeSingleStage(ModelInterpreter.groovy:666)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(ModelInterpreter.groovy:395)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(ModelInterpreter.groovy:393)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.executeSingleStage(ModelInterpreter.groovy:665)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:288)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.toolsBlock(ModelInterpreter.groovy:544)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.toolsBlock(ModelInterpreter.groovy:543)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:276)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(ModelInterpreter.groovy:443)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withEnvBlock(ModelInterpreter.groovy:442)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:275)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withCredentialsBlock(ModelInterpreter.groovy:481)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.withCredentialsBlock(ModelInterpreter.groovy:480)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.evaluateStage(ModelInterpreter.groovy:274)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.inDeclarativeAgent(ModelInterpreter.groovy:595)
    at org.jenkinsci.plugins.pipeline.modeldefinition.agent.CheckoutScript.checkoutAndRun(CheckoutScript.groovy:64)
    at org.jenkinsci.plugins.pipeline.modeldefinition.agent.CheckoutScript.doCheckout(CheckoutScript.groovy:40)
    at org.jenkinsci.plugins.pipeline.modeldefinition.agent.impl.LabelScript.run(LabelScript.groovy:43)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:73)
    at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:65)
    at jdk.internal.reflect.GeneratedMethodAccessor288.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
    at com.cloudbees.groovy.cps.Next.step(Next.java:83)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:152)
    at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:146)
    at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:136)
    at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:275)
    at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:146)
    at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:187)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:420)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:330)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:294)
    at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
    at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
    at jenkins.util.ErrorLoggingExecutorService.lambda$wrap$0(ErrorLoggingExecutorService.java:51)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Finished: FAILURE

Jenkins version: 2.387.1
Plugins:
Config as Code: 1569.vb_72405b_80249
config as code groovy extension: 1.1
pipeline: 596.v8c21c963d92d
pipeline groovy: 3653.v07ea_433c90b_4
pipeline groovy libraries: 629.vb_5627b_ee2104

And here is my script:

        pipeline {
            agent none
            parameters {
                choice(name: 'app', choices: ['app1', 'app2'], description: 'Select the app.')
                choice(name: 'app_year', choices: ['', '2023', '2022', '2021'], description: 'Select the app year.')
                choice(name: 'deploy_env', choices: ['builds'], description: 'Default is builds.')
                choice(name: 'feature', choices: ['', 'feat1', 'feat2', 'feat3'], description: 'Select the feature, leave blank for all.')
            }
            triggers {
                cron('H/15 * * * *')
            }
            stages {
                stage ('App Healthcheck') {
                    agent { label 'test-deploy01' }
                    options {
                        timeout(time: 3600, unit: 'SECONDS')
                    }
                    steps {
                        sh "cd /opt/tools/ansible/${app}/scripts/; \
                        PYTHONPATH=shared python app_service_check.py -y $app_year -e $deploy_env -p $feature"
                    }
                }
            }
        }

I pasted the above via the GUI. Clicked on New item --> Pipeline --> pasted groovy script on page and saved.

Ran the first time and got the error above. This however did register the parameters options in the job, and now I can run the job without issue and get prompted for each parameter and the script work no problem.

I need to load numerous jobs such as these via CasC, however Jenkins fails to start due to the above error, so I can't rerun the job in the GUI to get around this issue.

How can I solve this?

halfer
  • 19,824
  • 17
  • 99
  • 186
New2Python
  • 325
  • 1
  • 4
  • 17
  • Have you tried accessing the parameters via the `params` object, for example `"${params.app}"`? – IWilms Mar 31 '23 at 15:04
  • yes. I even did the def var = params.var then in the code ${var}. So again the odd issue is that when the job is run the first time there is the error, however the parameters get registered with Jenkins and any subsequent job runs fine. The script remains the same in the job's configuration. Very odd... – New2Python Mar 31 '23 at 16:44
  • This is how Jenkins works. If you have user interface in the job you need to run it once to mąkę it available for the user. Moreover, if you have some dynamic data in the interface it will only update when you run the job which means user always can see data from previous run only. UI is always one step behind. To handle this issue you either have to automatically run the job once after it is created or get rid of user interface. I recommend deleting parameters section if you can afford it. – grzegorzgrzegorz Mar 31 '23 at 21:41

1 Answers1

0

Yes @grzegorzgrzegorz it is how Jenkins works, which is odd to me. I got around it by setting up a pull pipeline job.

As an example:

In my Jenkins.yaml file I have:

jobs:
  - script: >
      folder('App')
  - file: /var/jenkins_home/pipelines/pull_stop_job

In my pull_job script I have this:

pipelineJob("App/Server Stop") {
  definition {
    cpsScm {
      scm {
        git {
          remote {
            url("https://gitlab.domian.com/Repo/Common/tools/jenkins.git")
            credentials("<gitlab_token>")
          }
          branch('develop')
        }
      }
      scriptPath("jobs/*")
    }
  }
  triggers {
    scm('H/15 * * * *')
  }
}

And then I can use that script I originally posted:

    pipeline {
        agent none
        parameters {
            choice(name: 'app', choices: ['app1', 'app2'], description: 'Select the app.')
            choice(name: 'app_year', choices: ['', '2023', '2022', '2021'], description: 'Select the app year.')
            choice(name: 'deploy_env', choices: ['builds'], description: 'Default is builds.')
            choice(name: 'feature', choices: ['', 'feat1', 'feat2', 'feat3'], description: 'Select the feature, leave blank for all.')
        }
        triggers {
            cron('H/15 * * * *')
        }
        stages {
            stage ('App Healthcheck') {
                agent { label 'test-deploy01' }
                options {
                    timeout(time: 3600, unit: 'SECONDS')
                }
                steps {
                    sh "cd /opt/tools/ansible/${app}/scripts/; \
                    PYTHONPATH=shared python app_service_check.py -y $app_year -e $deploy_env -p $feature"
                }
            }
        }
    }

As stated the job will fail the first time, but after that the job prompts for parameters correctly and can be used. Not perfect but it works.

New2Python
  • 325
  • 1
  • 4
  • 17