sous-chefs / jenkins

Development repository for the jenkins cookbook
https://supermarket.chef.io/cookbooks/jenkins
Apache License 2.0
424 stars 635 forks source link

Credentials creation fails with: unable to resolve class SchemeRequirement #123

Closed schisamo closed 10 years ago

schisamo commented 10 years ago

Issue originally reported by Tucker on the Chef mailing list: http://lists.opscode.com/sympa/arc/chef/2014-01/msg00219.html

Attempting to create credentials using the jenkins_private_key_credentials resource ends in the following exception:

Expected process to exit with [0], but received '255'
---- Begin output of java -jar /var/chef/cache/jenkins-cli.jar -s http://localhost:8080 groovy = <<-GROOVY_SCRIPT
        import com.cloudbees.plugins.credentials.impl.*;
        import com.cloudbees.jenkins.plugins.sshcredentials.impl.*;

                import jenkins.model.*
        import com.cloudbees.plugins.credentials.*
        import com.cloudbees.plugins.credentials.common.*
        import com.cloudbees.plugins.credentials.domains.*;

        username_matcher = CredentialsMatchers.withUsername("root")
        available_credentials =
          CredentialsProvider.lookupCredentials(
            StandardUsernameCredentials.class,
            Jenkins.getInstance(),
            hudson.security.ACL.SYSTEM,
            new SchemeRequirement("ssh")
          )

        credentials =
          CredentialsMatchers.firstOrNull(
            available_credentials,
            username_matcher
          )

        if(credentials == null) {
          return null
        }

        current_credentials = [
          id:credentials.id,
          description:credentials.description,
          username:credentials.username
        ]

        current_credentials['private_key'] = credentials.privateKey
current_credentials['passphrase'] = credentials.passphrase.plainText

        builder = new groovy.json.JsonBuilder(current_credentials)
        println(builder)

GROOVY_SCRIPT ----
STDOUT:
STDERR: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
RemoteClass: 15: unable to resolve class SchemeRequirement
 @ line 15, column 13.
               new SchemeRequirement("ssh")
               ^

1 error

        at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:302)
        at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:861)
        at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:550)
        at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:499)
        at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:302)
        at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:281)
        at groovy.lang.GroovyShell.parseClass(GroovyShell.java:731)
        at groovy.lang.GroovyShell.run(GroovyShell.java:516)
        at hudson.cli.GroovyCommand.run(GroovyCommand.java:94)
        at hudson.cli.CLICommand.main(CLICommand.java:229)
        at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:92)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at hudson.remoting.RemoteInvocationHandler$RPCRequest.perform(RemoteInvocationHandler.java:299)
        at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:280)
        at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:239)
        at hudson.remoting.UserRequest.perform(UserRequest.java:118)
        at hudson.remoting.UserRequest.perform(UserRequest.java:48)
        at hudson.remoting.Request$2.run(Request.java:326)
        at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
        at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:63)
        at hudson.remoting.InterceptingExecutorService$2.call(InterceptingExecutorService.java:95)
        at java.util.concurrent.FutureTask.run(FutureTask.java:262)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)

Full Chef output available here: https://gist.github.com/tucker-altiscale/6d31f71f425e66a3ad83

Issue reported on Jenkins 1.532-1.1 installed from packages on CentOS.

schisamo commented 10 years ago

I was able to recreate locally with the following tweak to my .kitchen.yml:

diff --git a/.kitchen.yml b/.kitchen.yml
index 4c8fd97..710a225 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -63,6 +63,10 @@ suites:
   #
   - name: jenkins_credentials_create
     run_list: jenkins_credentials::create
+    attributes:
+      jenkins:
+        master:
+          version: 1.532-1.1
   - name: jenkins_credentials_delete
     run_list: jenkins_credentials::delete
schisamo commented 10 years ago

Issue appears to be related to a downlevel version of the credentials plugin that ships with Jenkins 1.532-1.1. This version of Jenkins ships with credentials 1.4 which does not contain the class com.cloudbees.plugins.credentials.domains.SchemeRequirement. This class was first introduced with credentials 1.5: https://github.com/jenkinsci/credentials-plugin/commit/ea696cb21bc84bbe756334ef818450405432410a

schisamo commented 10 years ago

credentials 1.5 began shipping with Jenkins 1.536+: https://github.com/jenkinsci/jenkins/commit/2f846ea9a0c0714402c248c103b1d10c7fdb101f

tucker-altiscale commented 10 years ago

Comment so I can get updates.

Looks like a bit of a chicken and egg problem for me then. If I can get the plugin upgrade working, then it sounds like this should work as well. I probably won't have time to test until Saturday but I'll see what happens if I manually upgrade the plugin and then use the credentials resource.

it seems like there should be a sentinel around the credentials resource that blocks the execution attempt if the minimum plugin version isn't available and emits a warning.

sethvargo commented 10 years ago

@schisamo well that explains why we weren't seeing this behavior in our tests. I think we have to raise an error, since future command are likely to fail.

sethvargo commented 10 years ago

@schisamo @yzl talked about this in standup today. I don't think it's unreasonable to add a caveat to the README about this. Just like we require a minimum version or Ruby and Chef, we can require people manually install this plugin if they want to manage credentials.

tucker-altiscale commented 10 years ago

@sethvargo As a consumer of this cookbook, I think that's reasonable with the caveat that the jenkins_plugin resource (#122) should be able to handle upgrading said plugin.

sethvargo commented 10 years ago

@tucker-altiscale well... in recent versions of Jenkins, credentials is one of those "core" plugins

tucker-altiscale commented 10 years ago

@sethvargo I believe the credentials plugin is core for the LTS version of Jenkins as well. The issue is that upgrading a Jenkins plugin doesn't seem to be working, correct? That means that anyone using this cookbook and the LTS version of Jenkins has to have a different bootstrap recipe than they have for the long running service (append something to the run_list after launch and some hand configuration). It's not an unthinkable work flow but it's obviously not ideal. As I don't see many others chiming in, perhaps we're in the extreme minority with using the LTS version.