我该如何通过终端更新Jenkins插件?

32

我正在尝试创建一个用于设置Jenkins的bash脚本。是否有任何方法可以从Jenkins终端更新插件列表?

在第一次设置时,列表上没有可用的插件。

即:

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

无法工作

7个回答

47

一个简单但有效的方法是首先列出所有已安装的插件,查找更新并安装它们。

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

每个有可用更新的插件,在其末尾都会有新版本号括在括号里。所以你可以使用grep来搜索:

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

如果你使用插件名称调用install-plugin命令,它将自动升级到最新版本。

最后,你需要重启Jenkins。

将所有步骤放在一起(可以放在一个shell脚本中):

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

这是最佳答案,因为它不仅处理Jenkins插件本身的安装,还处理插件依赖的安装。 - Farrukh Najmi
你可能还需要按照 https://wiki.jenkins.io/display/JENKINS/Jenkins+CLI 的说明设置公钥身份验证。 - Ed Randall
1
在Jenkins中添加-auth @~/.ssh/jenkins.txt进行身份验证,例如:java -jar ~/tmp/jenkins-cli.jar -s https://jenkins.server.com -auth @~/.ssh/jenkins.txt list-plugins 其中~/.ssh/jenkins.txt是包含您的用户名:密码信息的文件。 - hit3k
1
谢谢,这是一个很好的答案!我只想补充一点,尽管我认为 Jenkins CLI 已经因为安全问题而被弃用/禁用了,但那只是旧的 RMI 协议。Jenkins 仍然支持通过 http、websocket 或 ssh 运行相同的 CLI 命令。使用 ssh 协议,您甚至不需要 jar 文件,只需 ssh -p $port jenkins.example.com list-plugins。请参阅 https://www.jenkins.io/doc/book/managing/cli/#ssh 了解如何设置它。 - andrewdotn
您可以通过以下方式下载Jenkins CLI .jar:https://www.jenkins.io/doc/book/managing/cli/#downloading-the-client - SantaXL
请注意,... | grep -e ')$' | awk '{ print $1 }' 可以缩短为 ... | awk ' /)$/ {print $1}'。少用一根管道。 - SiKing

34

您实际上可以从计算机终端(而非Jenkins终端)安装插件。

  1. 从插件站点(http://updates.jenkins-ci.org/download/plugins)下载插件
  2. 将该插件复制到$JENKINS_HOME/plugins目录中
  3. 此时启动Jenkins或调用重新加载设置服务(http://yourservername:8080/jenkins/reload

这将在Jenkins中启用插件,假设Jenkins已启动。

cd $JENKINS_HOME/plugins
curl -O http://updates.jenkins-ci.org/download/plugins/cobertura.hpi
curl http://yourservername:8080/reload

2
将更新的hpi/jpi文件复制到插件目录中也可以升级现有插件。我不知道/reload URL是否足以重新启动Jenkins,但通过UI使用“安全重启”(/safeRestart)可以完成所需操作。 - Eric
2
据我所知,以上操作不会安装正在安装的插件所需的依赖插件。 - Farrukh Najmi
这允许安装特定版本,谢谢。 - Gi0rgi0s
1
在第一个curl中添加“-L”标志可能是必需的,因为它通常会重定向到镜像。 - Helder Pereira
是的,我需要使用“-L”,否则内容只是一些重定向HTML。 - nh2

7

以下是如何使用Ansible部署Jenkins CI插件的方法,当然,这需要从终端中运行。此代码是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

这是一个更完整示例的一部分,您可以在以下链接找到: https://github.com/sakaal/service_platform_ansible/blob/master/roles/jenkins_ci/tasks/main.yaml 随意根据您的需要进行调整。

谢谢!看起来Ansible的get_url模块只会在文件不存在时获取文件,这意味着您的playbook只会安装新插件,而不是更新。这是正确的吗? - benzado
是的,我通过Jenkins Web UI更新它们。这只是它们的初始安装。有时拥有某些插件的特定版本非常重要,可以从UI中管理。当然,可以调整配置管理脚本来处理此问题,但我上面提供的方法对我来说非常有效。 - SAM
force=yes将会下载。 - bbaassssiiee
感谢您使用Ansible或任何自动配置工具。 - Mike D

3
您可以使用此命令行更新插件列表。
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

这个友好吗?也就是说,在没有作业运行时不会更新?我们不想因为插件更新而中断作业。 - sorin
@sorin,我十分确定你必须重新启动Jenkins才能加载新插件。所以你可以在执行该命令后安排一个安全重启。 - IcanDivideBy0
抱歉,但是一个合适的实现应该能够等待直到没有作业。即使当前的手动Web界面也有延迟重启的选项,直到没有正在运行的作业。 - sorin
据我所知,这不会更新插件本身,只会更新 Jenkins 对可用插件更新的信息。这相当于在/pluginManager中点击“立即检查”以刷新更新信息。 - Marius Gedminas
这对我来说失败了,出现了“org.acegisecurity.AccessDeniedException:浏览器下载已禁用”的错误。 - Marius Gedminas

1
FYI -- 一些插件(尤其是mercurial)如果不使用它们的简称,在命令行中安装可能会出现问题。我认为这与jenkins软件包信息数据中的触发器有关。您可以通过在支持JavaScript的浏览器中访问127.0.0.1:8080/pluginManager/checkUpdates来模拟jenkins自己的软件包更新。
或者,如果您想要挑战自己,可以运行以下Python代码:
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'

一旦您运行了这个命令,您应该能够运行 jenkins-cli -s http://127.0.0.1:8080 install-plugin mercurial -deploy


0

使用Groovy

Groovy路径有一个巨大的优势:可以在作业的“系统 Groovy 脚本”构建步骤中添加,无需进行任何更改。

创建文件 'update_plugins.groovy' 并包含以下内容:

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()
}

然后执行这个curl命令:

curl --user 'username:token' --data-urlencode "script=$(< ./update_plugins.groovy)" https://jenkins_server/scriptText

0

在当前的Jenkins版本中,CLI只能通过SSH使用。必须在管理界面的“全局安全设置”页面中启用此功能,如docs所述。此外,应触发更新的用户必须添加其公共SSH密钥。

使用已接受答案的修改后的shell脚本,可以按以下方式自动化操作,只需替换HOSTNAME和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

这个命令会查找Jenkins CLI使用的SSH端口,然后通过SSH连接而不检查主机密钥,因为每次Jenkins重启时它都会更改。

然后升级所有可用更新的插件,最后重新启动Jenkins。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接