puppet-jenkins icon indicating copy to clipboard operation
puppet-jenkins copied to clipboard

Jenkins Puppet Package provider discussion

Open matthewbarr opened this issue 11 years ago • 15 comments

I actually found a way to do some of what I want for plugins via groovy, which can be executed via a curl.

It was that, or the use the cli. CLI required Java, which was a pain.

Todo:

  • [ ] find a groovy method for installing a plugin
  • [ ] Maybe find a way to remove plugin via groovy.
  • [ ] parse plugin results so puppet can deal with it.

matthewbarr avatar Jul 05 '13 18:07 matthewbarr

For plugin list w/ version, from the unix command line:

curl -d @- http://jenkins301:8080/scriptText <<\EOF
script=def plugins=jenkins.model.Jenkins.instance.getPluginManager().getPlugins();plugins.each {println "${it.getShortName()} (${it.getVersion()})"}
EOF

matthewbarr avatar Jul 05 '13 18:07 matthewbarr

Groovy seems like a scary proposition, have you looked at the plugin manager API yet? See http://localhost:8080/pluginManager/api/

rtyler avatar Jul 05 '13 18:07 rtyler

Hadn't seen it yet. It doesn't seem to be able to show you the current list of plugins, at least not from: http://HOSTNAME:8080/pluginManager/api/xml

It might have a different end point. Which wouldn't suck, btw.

The groovy code i posted is only ugly because I wanted the name & version number.. if you just want the name, it's not so bad....

However, better ways to do this are always good. All I need is commands that can be run from ruby (or shell) to include in the package provider type for puppet. I came up w/ it a few months ago, but haven't had time to do work on it really, due to - real work.

matthewbarr avatar Jul 05 '13 19:07 matthewbarr

I'm going to take this ticket over and look into prototyping something for the Duckworth release

rtyler avatar Feb 25 '14 05:02 rtyler

Please, do! My ruby has probably gotten to the point where I could do this.. but... my time isn't available. If i write code, i'm probably going to be writing monitoring code or such to integrate flapjack, sensu, mcollective and other things...

matthewbarr avatar Feb 25 '14 05:02 matthewbarr

@matthewbarr FYI, I've decided to move my work out of the puppet-jenkins repository on this and to create a general purpose ruby gem which we can integrate: the Jenkins Plugin Manager

I've spoken with some of the Puppet folks, and unfortunately there's not a good way to include a gem inside of a Puppet module. I'm planning to submodule the gem into the repository and do something like this (FYI):

begin
  require 'jpm/api'
  raise StandardError if JPM::Version < '1.0'
rescue LoadError, StandardError => ex
  # Can't load the gem from the file system, let's dig it out of the module package
  require 'puppet/jenkins/gems/jpm/api'
end

This way if somebody has the gem installed, and of the appropriate version, we'll just use that, otherwise default to the one we have. "Why not always use the one in the module?" I would assume you're thinking. My belief is that by trying to install from the system, we can pick up non-API breaking changes/fixes without needing to always update a release of the Puppet module.

rtyler avatar Mar 14 '14 15:03 rtyler

@rtyler, I remember hearing discussion about using a custom puppet provider for this. Is that still part of the plan or no?

jchristi avatar Apr 16 '14 14:04 jchristi

@jchristi Most definitely! I've been making some progress with this but the past couple weekends I've not had the time. Fingers crossed for this weekend :)

rtyler avatar Apr 16 '14 16:04 rtyler

@jchristi is what you're using based on the jpm work that I already did, or based off something else?

rtyler avatar Apr 16 '14 16:04 rtyler

@rtyler, oops, wrong issue.

jchristi avatar Apr 16 '14 17:04 jchristi

Also, good to hear about the custom provider approach (I probably could have inferred that had I read the title!)

jchristi avatar Apr 16 '14 17:04 jchristi

What's the status of this? Has it been abandoned in favor of another method or is resourcing the constraint?

lewisheadden avatar Jan 09 '16 02:01 lewisheadden

@lewisheadden As-is, it is better to manage plugins completely behind Jenkins' back due to internal API limitations (read: oh-the-horrors-I-have-seen). It appears that the chef community has come to the same conclusion.

jhoblitt avatar Jan 19 '16 23:01 jhoblitt

@matthewbarr / @rtyler What do you guys want to do with this issue? I spent several days banging my head against the wall trying to implement this by calling Jenkins' API. There's missing functionality, the update center is a bit wacky, and the async nature of plugin installation is a PITA to deal with. I may have code on a branch somewhere but my conclusion was that it was much was both easier and provided more functionality to manage plugins behind jenkins' back.

jhoblitt avatar Jan 19 '16 23:01 jhoblitt

I poked around the API and I found that this code works very well for us (but needs to be improved to check if/wait until Jenkins is running and lots of other stuff):

    define my::jenkins_plugin ($ensure = 'present') {
      if !($ensure in ['present', 'absent']) {
        fail('jenkins_plugin ensure parameter must be absent or present')
      }
      include my::jenkins_tools
      $jenkins_url = 'http://localhost:8080'

      if ($ensure == 'present') {
        exec { "Install Jenkins $title plugin":
          command => "/usr/bin/curl -f ${jenkins_url}/pluginManager/install?plugin.${title}.default",
          unless  => "/usr/bin/curl -f ${jenkins_url}/updateCenter/plugin/${title}/api/xml?xpath=plugin/installed",
          notify  => Exec['Soft Restart Jenkins'],
          require => Service['jenkins'],
        }
      } else {
        exec { "Uninstall Jenkins $title plugin":
          command => "/usr/bin/curl -XPOST -f ${jenkins_url}/pluginManager/plugin/${title}/doUninstall",
          onlyif  => "/usr/bin/curl -f ${jenkins_url}/updateCenter/plugin/${title}/api/xml?xpath=plugin/installed",
          notify  => Exec['Soft Restart Jenkins'],
          require => Service['jenkins'],
        }
      }
    }

    class my::jenkins_tools {
      exec { 'Soft Restart Jenkins':
        command     => '/usr/bin/curl -f http://localhost:8080/updateCenter/safeRestart',
        refreshonly => true,
      }
    }

Let me know if you're interested, then I will expand on this POC.

seidler2547 avatar Apr 20 '16 14:04 seidler2547