How can I update jenkins plugins from the terminal?
Asked Answered
D

7

35

I am trying to create a bash script for setting up Jenkins. Is there any way to update a plugin list from the Jenkins terminal?

At first setup there is no plugin available on the list

i.e.:

java -jar jenkins-cli.jar -s `http://localhost:8080` install-plugin dry

won't work

Doeskin answered 10/10, 2011 at 8:5 Comment(0)
J
48

A simple but working way is first to list all installed plugins, look for updates and install them.

java -jar /root/jenkins-cli.jar -s http://127.0.0.1:8080/ list-plugins

Each plugin which has an update available, has the new version in brackets at the end. So you can grep for those:

java -jar /root/jenkins-cli.jar -s http://127.0.0.1:8080/ list-plugins | grep -e ')$' | awk '{ print $1 }'

If you call install-plugin with the plugin name, it is automatically upgraded to the latest version.

Finally you have to restart jenkins.

Putting it all together (can be placed in a shell script):

UPDATE_LIST=$( java -jar /root/jenkins-cli.jar -s http://127.0.0.1:8080/ list-plugins | grep -e ')$' | awk '{ print $1 }' ); 
if [ ! -z "${UPDATE_LIST}" ]; then 
    echo Updating Jenkins Plugins: ${UPDATE_LIST}; 
    java -jar /root/jenkins-cli.jar -s http://127.0.0.1:8080/ install-plugin ${UPDATE_LIST};
    java -jar /root/jenkins-cli.jar -s http://127.0.0.1:8080/ safe-restart;
fi
Jobina answered 3/9, 2014 at 15:6 Comment(6)
This is the best answer because it handles installation of jenkins plugin dependencies in addition to the plugins themselves.Retiring
You likely also need to set up public key authentication, as per wiki.jenkins.io/display/JENKINS/Jenkins+CLIDietsche
Add -auth @~/.ssh/jenkins.txt for authentication to your Jenkins, like: java -jar ~/tmp/jenkins-cli.jar -s https://jenkins.server.com -auth @~/.ssh/jenkins.txt list-plugins ~/.ssh/jenkins.txt is a file containing your username:passwordManus
Thanks, this is a great answer! I just wanted to add that though I thought the jenkins CLI was deprecated/disabled due to security issues, that was just the old RMI protocol. Jenkins still supports running the same CLI commands over http, websocket, or ssh. With the ssh protocol, you don’t even need the jar, just ssh -p $port jenkins.example.com list-plugins See jenkins.io/doc/book/managing/cli/#ssh for how to set that up.Jehius
You can download Jenkins CLI .jar like this: jenkins.io/doc/book/managing/cli/#downloading-the-clientMoneychanger
Note that ... | grep -e ')$' | awk '{ print $1 }' can be shortened to ... | awk ' /)$/ {print $1}'. One less pipe.Champignon
T
34

You can actually install plugins from the computer terminal (rather than the Jenkins terminal).

  1. Download the plugin from the plugin site (http://updates.jenkins-ci.org/download/plugins)
  2. Copy that plugin into the $JENKINS_HOME/plugins directory
  3. At that point either start Jenkins or call the reload settings service (http://yourservername:8080/jenkins/reload)

This will enable the plugin in Jenkins and assuming that Jenkins is started.

cd $JENKINS_HOME/plugins
curl -O http://updates.jenkins-ci.org/download/plugins/cobertura.hpi
curl http://yourservername:8080/reload
Thermomagnetic answered 14/2, 2012 at 0:11 Comment(5)
Copying an updated hpi/jpi file into the plugins directory also works to upgrade an existing plugin. I don't know whether the /reload url is sufficient to restart Jenkins, but using the "Restart Safely" (/safeRestart) through the UI does what's needed.Shipworm
Above will not install dependency plugins for the plugin being installed AFAIK.Retiring
This allows for installation of specific versions, thanks.Ontiveros
Adding -L flag in the first curl is likely to be required, as it usually redirects to a mirror.Crunch
Yes, I needed -L otherwise the contents was just some redirect HTML.Parliamentarian
D
7

Here is how you can deploy Jenkins CI plugins using Ansible, which of course is used from the terminal. This code is a part of roles/jenkins_ci/tasks/main.yaml:

- name: Plugins
  with_items:                             # PLUGIN NAME
  - name: checkstyle                      # Checkstyle
  - name: dashboard-view                  # Dashboard View
  - name: dependency-check-jenkins-plugin # OWASP Dependency Check
  - name: depgraph-view                   # Dependency Graph View
  - name: deploy                          # Deploy
  - name: emotional-jenkins-plugin        # Emotional Jenkins
  - name: monitoring                      # Monitoring
  - name: publish-over-ssh                # Publish Over SSH
  - name: shelve-project-plugin           # Shelve Project
  - name: token-macro                     # Token Macro
  - name: zapper                          # OWASP Zed Attack Proxy (ZAP)
  sudo: yes
  get_url: dest="{{ jenkins_home }}/plugins/{{ item.name | mandatory }}.jpi"
           url="https://updates.jenkins-ci.org/latest/{{ item.name }}.hpi"
           owner=jenkins group=jenkins mode=0644
  notify: Restart Jenkins

This is a part of a more complete example that you can find at: https://github.com/sakaal/service_platform_ansible/blob/master/roles/jenkins_ci/tasks/main.yaml

Feel free to adapt it to your needs.

Decennary answered 15/11, 2014 at 23:43 Comment(4)
Thanks for this! It looks like the Ansible get_url module will only fetch a file if it doesn't already exist, which means your playbook would only install new plugins, not update. Is that correct?Deflower
Yes, I am updating them via the Jenkins Web UI. This does only their initial installation. It is sometimes important to have a specific version of some plugin, which can be managed from the UI. Of course it is possible to tweak the configuration management script to handle that, but the approach I gave above works for me really well.Decennary
force=yes will downloadGinkgo
props for using Ansible or any automated config tool for that matter.Kalila
S
2

You can update plugins list with this command line

curl -s -L http://updates.jenkins-ci.org/update-center.json | sed '1d;$d' | curl -s -X POST -H 'Accept: application/json' -d @- http://localhost:8080/updateCenter/byId/default/postBack
Socialist answered 13/10, 2014 at 15:26 Comment(5)
Is this friendly? As in not updating until there is no job running? We do not want to brake jobs to do plugin updates.Organdy
@Organdy I'm pretty sure you'll have to restart jenkins to get new plugins loaded. So you can planify a safe-restart after this command.Socialist
sorry but a proper implementation should be able to wait till there are no jobs. Even the current manual web interface has the option to delay restart till there are no jobs running.Organdy
AFAIU this doesn't update the plugins themselves, only the information Jenkins has about available plugin updates. It's the equivalent of hitting "Check now" in /pluginManager to refresh update information.Heptahedron
This fails for me with a "org.acegisecurity.AccessDeniedException: browser-based download disabled".Heptahedron
S
1

FYI -- some plugins (mercurial in particular) don't install correctly from the command line unless you use their short name. I think this has to do with triggers in the jenkins package info data. You can simulate jenkins' own package update by visiting 127.0.0.1:8080/pluginManager/checkUpdates in a javascript-capable browser.

Or if you're feeling masochistic you can run this python code:

import urllib2,requests

UPDATES_URL = 'https://updates.jenkins-ci.org/update-center.json?id=default&version=1.509.4'
PREFIX = 'http://127.0.0.1:8080'

def update_plugins():
    "look at the source for /pluginManager/checkUpdates and downloadManager in /static/<whatever>/scripts/hudson-behavior.js"
    raw = urllib2.urlopen(self.UPDATES_URL).read()
    jsontext = raw.split('\n')[1] # ugh, JSONP
    json.loads(jsontext) # i.e. error if not parseable
    print 'received updates json'

    # post
    postback = PREFIX+'/updateCenter/byId/default/postBack'
    reply = requests.post(postback,data=jsontext)
    if not reply.ok:
        raise RuntimeError(("updates upload not ok",reply.text))
    print 'applied updates json'

And once you've run this, you should be able to run jenkins-cli -s http://127.0.0.1:8080 install-plugin mercurial -deploy.

Spickandspan answered 16/10, 2013 at 21:11 Comment(0)
S
0

With a current Jenkins Version, the CLI can just be used via SSH. This has to be enabled in the "Global Security Settings" page in the administration interface, as described in the docs. Furthermore, the user who should trigger the updates must add its public ssh key.

With the modified shell script from the accepted answer, this can be automatized as follows, you just have to replace HOSTNAME and USERNAME:

#!/bin/bash

jenkins_host=HOSTNAME #e.g. jenkins.example.com
jenkins_user=USERNAME

jenkins_port=$(curl -s --head https://$jenkins_host/login | grep -oP "^X-SSH-Endpoint: $jenkins_host:\K[0-9]{4,5}")

function jenkins_cli {
    ssh -o StrictHostKeyChecking=no -l "$jenkins_user" -p $jenkins_port "$jenkins_host" "$@"
}

UPDATE_LIST=$( jenkins_cli list-plugins | grep -e ')$' | awk '{ print $1 }' ); 

if [ ! -z "${UPDATE_LIST}" ]; then 
    echo Updating Jenkins Plugins: ${UPDATE_LIST}; 
    jenkins_cli install-plugin ${UPDATE_LIST};
    jenkins_cli safe-restart;
else
    echo "No updates available"
fi

This greps the used SSH port of the Jenkins CLI and then connects via SSH without checking the host key, as it changes for every Jenkins restart.

Then all plugins with an update available are upgraded and afterwards Jenkins is restarted.

Shortstop answered 25/7, 2020 at 10:11 Comment(0)
I
0

In groovy

The groovy path has one big advantage: it can be added to a 'system groovy script' build step in a job without any change.

Create the file 'update_plugins.groovy' with this content:

jenkins.model.Jenkins.getInstance().getUpdateCenter().getSites().each { site ->
  site.updateDirectlyNow(hudson.model.DownloadService.signatureCheck)
}
hudson.model.DownloadService.Downloadable.all().each { downloadable ->
  downloadable.updateNow();
}
def plugins = jenkins.model.Jenkins.instance.pluginManager.activePlugins.findAll {
  it -> it.hasUpdate()
}.collect {
  it -> it.getShortName()
}
println "Plugins to upgrade: ${plugins}"
long count = 0
jenkins.model.Jenkins.instance.pluginManager.install(plugins, false).each { f ->
  f.get()
  println "${++count}/${plugins.size()}.."
}
if(plugins.size() != 0 && count == plugins.size()) {
  println "restarting Jenkins..."
  jenkins.model.Jenkins.instance.safeRestart()
}

Then execute this curl command:

curl --user 'username:token' --data-urlencode "script=$(< ./update_plugins.groovy)" https://jenkins_server/scriptText
Invalidate answered 4/11, 2022 at 7:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.