Search code examples
jenkinsgroovyactive-directorychef-infrarhel7

Jenkins active-directory Could not find matching constructor


Caution: I'm good with EnterpriseLinux, but assume I'm a reluctant pedestrian at best for Jenkins, jars, wars, jpis, java, and groovy. I'm so sorry.

I've got a Jenkins box set up on RHEL7, mainly via the (admittedly rotting) Chef cookbook, so it's repeatable and nearly idiot-proof. When it comes to adding the module, I'm adding the HPIs by local file (secure site, no net access) like so:

plugins=%w(active-directory mailer display-url-api)
require 'digest'

plugins
  .each_with_index do |plugin_with_version, index|
  p, v = plugin_with_version.split(':')  # yeah I know

  source = "#{Chef::Config[:file_cache_path]}/cookbooks/#{cookbook_name}/files/default/#{p}.hpi"

  directory  "#{node['jenkins']['master']['home']}/plugins" do
      owner     node['jenkins']['master']['user']
      group     node['jenkins']['master']['group']
      mode      0755
    end

    cookbook_file "#{node['jenkins']['master']['home']}/plugins/#{p}.hpi" do
      action    :create
      owner     node['jenkins']['master']['user']
      group     node['jenkins']['master']['group']
      mode      0755
      notifies  :create, "ruby_block[jenkins_restart_flag]", :immediately
    end
end

When I pre-game the files portion with HPIs, it populates the /var/lib/jenkins/plugins location, so I think I'm getting there.

# ls -l /var/lib/jenkins/plugins/
total 708
drwxr-xr-x 6 jenkins jenkins     77 Aug 30 08:37 active-directory
-rwxr-xr-x 1 jenkins jenkins 583280 Aug 30 08:37 active-directory.hpi
drwxr-xr-x 4 jenkins jenkins     53 Aug 30 08:37 display-url-api
-rwxr-xr-x 1 jenkins jenkins  19478 Aug 30 08:37 display-url-api.hpi
drwxr-xr-x 4 jenkins jenkins     53 Aug 30 08:37 mailer
-rwxr-xr-x 1 jenkins jenkins 115745 Aug 30 08:37 mailer.hpi

In fact, all three plugins seem to be active in /pluginManager/installed:

active directory plugin  2.8
Display URL API          2.2.0
Mailer Plugin            1.21

.. and the two deps have their boxes checked and dimmed, where the AD plugin is just checked. That suggests that they're installed and activated, but I'm guessing.

Now to configuring the AD plugin, I think, and here's where things go horribly wrong today.

Here's the script I'm using, about the 5th such script (Google's my only friend here when the brain's outta clues):

import hudson.plugins.active_directory.*
import jenkins.model.*

def instance = Jenkins.getInstance();
def ActiveDirectoryDomain adDomain = new ActiveDirectoryDomain("Example_Domain_Name_2", "Example_Domain_Controller_\
2");
def domains = new ArrayList<ActiveDirectoryDomain>();
domains.add(adDomain);

def securityRealm = new ActiveDirectorySecurityRealm(
"",
domains,
"",
"",
"",
"",
GroupLookupStrategy.RECURSIVE,
false,
true,
null)
println(securityRealm.domains)

instance.setSecurityRealm(securityRealm)
instance.save()

But the invocation totally bails. The meat of the error message, removing the chef bleating, is:

---- Begin output of "/usr/lib/jvm/java-1.8.0/bin/java" -jar "/var/chef/cache/jenkins-cli.jar" -s http://localhost:8080 -"remoting" groovy = ----
STDOUT:
STDERR: Aug 30, 2018 1:32:03 PM org.jenkinsci.remoting.util.AnonymousClassWarnings warn
WARNING: Attempt to (de-)serialize anonymous class hudson.cli.ClientAuthenticationCache$1; see: https://jenkins.io/redirect/serialization-of-anonymous-classes/

ERROR: Unexpected exception occurred while performing groovy command.
groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hudson.plugins.active_directory.ActiveDirectorySecurityRealm(java.lang.String, java.util.ArrayList, java.lang.String, java.lang.String, java.lang.String, java.lang.String, hudson.plugins.active_directory.GroupLookupStrategy, java.lang.Boolean, java.lang.Boolean, null)
        at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1732)
        at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1532)
        at org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructor(MetaClassConstructorSite.java:49)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
        at RemoteClass.run(RemoteClass:9)
        at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
        at groovy.lang.GroovyShell.run(GroovyShell.java:518)
        at groovy.lang.GroovyShell.run(GroovyShell.java:497)
        at hudson.cli.GroovyCommand.run(GroovyCommand.java:89)
        at hudson.cli.CLICommand.main(CLICommand.java:280)
        at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:95)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:929)
        at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:903)
        at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:855)
        at hudson.remoting.UserRequest.perform(UserRequest.java:212)
        at hudson.remoting.UserRequest.perform(UserRequest.java:54)
        at hudson.remoting.Request$2.run(Request.java:369)
        at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
        at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:66)
        at hudson.remoting.CallableDecoratorAdapter.call(CallableDecoratorAdapter.java:18)
        at hudson.remoting.CallableDecoratorList$1.call(CallableDecoratorList.java:21)
        at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
        at jenkins.security.ImpersonatingExecutorService$2.call(ImpersonatingExecutorService.java:71)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
---- End output of "/usr/lib/jvm/java-1.8.0/bin/java" -jar "/var/chef/cache/jenkins-cli.jar" -s http://localhost:8080 -"remoting" groovy = ----

No Joy, right? Here's the choicest cut:

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hudson.plugins.active_directory.ActiveDirectorySecurityRealm(java.lang.String, java.util.ArrayList, java.lang.String, java.lang.String, java.lang.String, java.lang.String, hudson.plugins.active_directory.GroupLookupStrategy, java.lang.Boolean, java.lang.Boolean, null)

Now, before we dive into this one, I do want to say that the other (really 3 or 4) scripts I also tried, like the Internet van-candy it is, also bailed with similar constructor errors. I can run those and present the errors for comparison if need be, but what I want to suggest is that it smells like a larger problem, that somehow my addons aren't dropping in the code they should be, even though it all looks okay. Again, still guessing.

And yes, in the other 3-4 attempts I tuned the scripts with internal custom data; this one, with morale so low, I didn't even bother. But I promise that I used valid data with the rest, and the plan is to use real values if we can get past the constructor error.

And the questions, in a very particular order:

  1. what's a known-good invocation for groovy to create that AD config? With the most recent of what appears to be a very changing codebase?
  2. Has anyone else seen this groovy constructor issue with a similar-ish setup?
  3. Any hints to get me closer to a win?

Thanks for reading this far, and I hope your day is going very well. ;-)


Solution

  • So all Groovy scripting in Jenkins is a very thin layer over the actual Java objects, so to find the right constructor, we need to look at the code for the plugin: https://github.com/jenkinsci/active-directory-plugin/blob/1b082cbfb7d236d326c218c7b474fb51cb930080/src/main/java/hudson/plugins/active_directory/ActiveDirectorySecurityRealm.java#L224-L270

    If we take the first constructor as an example:

    ActiveDirectorySecurityRealm(String domain, String site, String bindName, String bindPassword, String server)
    

    So you would call that like:

    def securityRealm = new ActiveDirectorySecurityRealm("Example_Domain_Name_2", null, null, null,  "Example_Domain_Controller_2")
    

    Or something like that.