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

Cannot get property 'plainText' on null object #591

Open valter-silva-au opened 7 years ago

valter-silva-au commented 7 years ago

Cookbook version

5.0.0

Chef-client version

12.19.36

Platform Details

Ubuntu 16.04

Scenario:

Use resource jenkins_private_key_credentials.

Steps to Reproduce:

jenkins_private_key_credentials 'application' do
  id          'application-key'
  description 'Application access key to BitBucket'
  private_key "-----BEGIN RSA PRIVATE KEY-----\n ... somekey ...\n\n-----END RSA PRIVATE KEY-----"
  action :create
end

Expected Result:

Create credential with the provided private key.

Actual Result:

* jenkins_private_key_credentials[application] action create[2017-04-04T09:52:50+02:00] INFO: Processing jenkins_private_key_credentials[application] action create (anevis_jenkins::users line 36)

 ================================================================================
 Error executing action `create` on resource 'jenkins_private_key_credentials[application]'
 ================================================================================

 Mixlib::ShellOut::ShellCommandFailed
 ------------------------------------
 Expected process to exit with [0], but received '1'
 ---- Begin output of "java" -jar "/tmp/kitchen/cache/jenkins-cli.jar" -s http://localhost:8080 -i "/tmp/kitchen/cache/jenkins-key" groovy /tmp/groovy20170404-6613-3plsq6 ----
 STDOUT: 
 STDERR: ERROR: Unexpected exception occurred while performing groovy command.
 java.lang.NullPointerException: Cannot get property 'plainText' on null object
    at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:60)
    at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:172)
    at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty(NullCallSite.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:296)
    at RemoteClass.run(RemoteClass:38)
    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:265)
    at hudson.cli.CliManagerImpl.main(CliManagerImpl.java:93)
    at sun.reflect.GeneratedMethodAccessor285.invoke(Unknown Source)
    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:895)
    at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:870)
    at hudson.remoting.RemoteInvocationHandler$RPCRequest.call(RemoteInvocationHandler.java:829)
    at hudson.remoting.UserRequest.perform(UserRequest.java:153)
    at hudson.remoting.UserRequest.perform(UserRequest.java:50)
    at hudson.remoting.Request$2.run(Request.java:336)
    at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:68)
    at hudson.cli.CliManagerImpl$1.call(CliManagerImpl.java:64)
    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 java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
 ---- End output of "java" -jar "/tmp/kitchen/cache/jenkins-cli.jar" -s http://localhost:8080 -i "/tmp/kitchen/cache/jenkins-key" groovy /tmp/groovy20170404-6613-3plsq6 ----
 Ran "java" -jar "/tmp/kitchen/cache/jenkins-cli.jar" -s http://localhost:8080 -i "/tmp/kitchen/cache/jenkins-key" groovy /tmp/groovy20170404-6613-3plsq6 returned 1

 Cookbook Trace:
 ---------------
 /tmp/kitchen/cache/cookbooks/jenkins/libraries/_executor.rb:85:in `execute!'
 /tmp/kitchen/cache/cookbooks/jenkins/libraries/_executor.rb:138:in `groovy!'
 /tmp/kitchen/cache/cookbooks/jenkins/libraries/credentials.rb:227:in `current_credentials'
 /tmp/kitchen/cache/cookbooks/jenkins/libraries/credentials_private_key.rb:128:in `current_credentials'
 /tmp/kitchen/cache/cookbooks/jenkins/libraries/credentials.rb:68:in `load_current_resource'
 /tmp/kitchen/cache/cookbooks/jenkins/libraries/credentials_user.rb:42:in `load_current_resource'
 /tmp/kitchen/cache/cookbooks/jenkins/libraries/credentials_private_key.rb:80:in `load_current_resource'

 Resource Declaration:
 ---------------------
 suppressed sensitive resource output

 Compiled Resource:
 ------------------
 suppressed sensitive resource output

 Platform:
 ---------
 x86_64-linux

If I remove the credentials via Jenkins web interface and try to converge, it works, but if I try to converge again, with the credential already created, it doesn't. Am I missing something ?

Thank you very much!

axos88 commented 7 years ago

+1

pielu commented 7 years ago

+1

axos88 commented 7 years ago

Workaround for now, to remove the credentials during each chef run and then recreate it:

jenkins_script 'hack around issue 591' do
  command <<-EOH
    import jenkins.model.*
    import com.cloudbees.plugins.credentials.*;
    import com.cloudbees.plugins.credentials.*
    import com.cloudbees.plugins.credentials.common.*
    import com.cloudbees.plugins.credentials.domains.*;
    global_domain = com.cloudbees.plugins.credentials.domains.Domain.global()
    credentials_store =
      Jenkins.instance.getExtensionList(
        'com.cloudbees.plugins.credentials.SystemCredentialsProvider'
      )[0].getStore()
    id_matcher = CredentialsMatchers.withId("REPLACE_ME_WITH_CREDENTIAL_ID")
    available_credentials =
      CredentialsProvider.lookupCredentials(
        StandardUsernameCredentials.class,
        Jenkins.instance,
        hudson.security.ACL.SYSTEM,
        new SchemeRequirement("ssh")
      )
    existing_credentials =
      CredentialsMatchers.firstOrNull(
        available_credentials,
        id_matcher
      )
    if(existing_credentials != null) {
      credentials_store.removeCredentials(
        global_domain,
        existing_credentials
      )
    }
  EOH
end
jayhendren commented 7 years ago

any updates on this bug?

stuszynski commented 7 years ago

@Poohblah https://github.com/chef-cookbooks/jenkins/pull/597 works fine to me as a workaround

jayhendren commented 7 years ago

I meant updates from the project maintainers. I would really like to see #597 merged.

jayhendren commented 7 years ago

I've got what I believe to be a better workaround. Rather than delete and re-create the credentials every time, check to see if credentials.xml contains the credentials:

jenkins_private_key_credentials 'mycreds' do
  id 'mycreds'
  private_key key
  not_if do
    credentials_file = '/var/lib/jenkins/credentials.xml'
    matcher = '<description>Credentials for mycreds - created by Chef</description>'
    re = /#{Regexp.quote matcher}/
    File.exist?(credentials_file) && File.readlines(credentials_file).grep(re).any?
  end
end