configuration-as-code-plugin: casc reload groovy command breaks jobdsl plugin if executed by pipeline step load()
Your checklist for this issue
-
Jenkins version: 2.190.3
-
Plugin version: 1.34
-
OS: docker image based on jenkins/jenkins:lts
Description
If jobs section is present in jenkins.yaml, configuration reload fails, both via UI and groovy script. Jobs config works without any issues on init, but fails on reload. CASC_JENKINS_CONFIG is set to url.
Config example:
jobs:
- script: >
folder('xxx')
Error: groovy.lang.MissingMethodException: No signature of method: javaposse.jobdsl.plugin.JenkinsDslScriptLoader.customizeCompilerConfiguration() is applicable for argument types: (org.codehaus.groovy.control.CompilerConfiguration) values: [org.codehaus.groovy.control.CompilerConfiguration@67233c11]
Full trace: https://pastebin.com/0A2Mtz8z
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 19 (10 by maintainers)
To be honest, that page is quite lacking some important details. Like example of Jenkins CLI command or mention that only system groovy script will work… Should I maybe just create PR for that? 😃
I was able to find the root of this issue: forgot to remove
load('reload.groovy')
step from test job created by jobdsl 🤦🏻♂️ so seed job and reload job were working correctly but then test job was built by branch indexing and breaking jobdsl plugin…Conclusion: using
load
pipeline step to run casc reload groovy command effectively breaks jobdsl plugin. Guess it’s a lack of permissions, but quite weird that it’s affecting jobdsl plugin in such way.P.S. Maybe it will be useful for someone, my configs for casc reload:
jobdsl for reload job:
declarative pipeline step to trigger reload:
required permissions in casc:
Do you have any recommendations on how to automatically reload it securely then?
I think this is all really just working around the fact that JCaC offers no native way to automatically sync configuration from an external (preferably private) repository. The lack of that makes it largely useless IMO, because users have to, each time they make changes, go to the JCasC page and point it to the correct location to pull configuration from. And from looking, I couldn’t personally find a way to POST the JCasC in any officially documented way. Paired with the difficulty involved in figuring out what to put in there in the first place, it hardly feels worth the effort of using
Maybe this rant would be best suited to exist in a separate feature request for JCasC, or someone could point out to my why/how the suggestion is insecure
I guess my thinking is that running any of those documented methods (including OP’s workaround) from a pipeline defeats the security model as far as I understand. It feels like using the API or the CLI is even worse as it requires adding credentials to Jenkins that need system administer access (please correct me if I’m wrong). Surely allowing a pipeline to only reload the configuration (without additional changes) is non-destructive. If the pipeline doesn’t have access to make changes to file system, then it is futile to invoke a reload as it will just load up what was already there.
In our case, we are already trusting our Jenkins repo to update the jobs, and it also contains our full infrastructure for Jenkins. Perhaps what is needed is a pipeline step to do a reload that doesn’t break the security model, e.g. it requires running the pipeline as a user or something (I don’t know if such functionality exists for declarative pipelines). Or better yet, maybe a new permission can be introduced for reloading configuration. The latter would be nice as it allows creation of a user that only has access to that, thus limiting the blast radius.
Regardless of all of that, there is a bug that in my opinion needs fixing. Running
ConfigurationAsCode.get().configure()
from a declarative pipeline seems to put Jenkins in a bad state where this plugin cannot be reloaded until after a restart (with the stack trace in OP’s link) regardless of who does it or what mechanisms is used. As an example, in my local environment I’m admin and after running the code in a declarative pipeline once, I’m unable to reload it at all even if I go into the administer UI, or use the API, both with valid credentials and permissions. I’m raising a PR after this comment to document this in the config reload docs, but it would be nice to have a proper fix in place. If you like, I can raise a separate issue to address this.