获取Jenkins作业使用的插件

2 投票
1 回答
2184 浏览
提问于 2025-04-18 05:27

我写了一个Python脚本,用来获取每个Jenkins任务所使用的插件列表。

#!/usr/bin/python

import os

mypath = '/work/jenkins/jobs' for root, subFolders,
files in os.walk(mypath):   if 'config.xml' in files:
      with open(os.path.join(root, 'config.xml'), 'r') as fin:
         for lines in fin:
             if 'plugin=' in lines:
                before_keyword,keyword,after_keyword = lines.partition('plugin=')
                print root,after_keyword

它会输出以下内容,例如:

/work/jenkins/jobs/job1 "subversion@2.2">

/work/jenkins/jobs/job1 "ant@1.2">

/work/jenkins/jobs/job1 "ant@1.2">

/work/jenkins/jobs/job2 "maven-plugin@2.1">

/work/jenkins/jobs/job2 "subversion@2.2">
  1. 有没有人能帮我调整一下我的程序,让输出看起来更好一些?
  2. 这个只打印了任务使用的插件。我怎么才能获取Jenkins系统使用的插件(比如活动目录等)呢?
  3. 我想把这个输出复制粘贴到Excel里,一列是任务名,另一列是使用的插件。我的输出应该简单到可以直接转移。
  4. job1显示了ant@1.2两次。我怎么才能去掉一个?
  5. job1和job2共享一个插件(subversion@2.2)。虽然我希望最开始的输出能显示这一点(这样我可以找到哪个任务使用了哪个插件),但我也想要一个去掉重复项的输出。我该怎么做呢?

更新:我注意到我可以从/work/jenkins/config.xml获取一些系统插件的信息,但这个列表不完整。

任何帮助都很感激。谢谢!

1 个回答

4

编辑:

这里是满足要求1、2、3、4和5的代码;我没能完成要求2,因为我不知道怎么做我想我在要求2上做得对吧?:

#!/usr/bin/env python2
# coding: utf-8
# Veni Sancte Spiritus

# This code is under public domain.

import os
import argparse
import logging
import re
import openpyxl

logging.basicConfig(
    format="[%(levelname)s]: %(message)s", level=logging.INFO)

try:
    import openpyxl
except ImportError:
    logging.error("Install openpyxl; pip install openpyxl")
    exit(1)

parser = argparse.ArgumentParser(description="get plugins used by Jenkins job")
parser.add_argument("--excel", metavar="dir/output1.xslx",
                    help="Output to excel file")

parser.add_argument("--jenkinshome", metavar="/var/lib/jenkins",
                    help="Jenkins home location (default: {})".format(
                        os.getcwd()), default=os.getcwd())

arguments = parser.parse_args()

alreadyadded = []
pluginsalreadyadded = {}

if arguments.excel:
    workbook = openpyxl.Workbook(optimized_write=True)
    worksheet1 = workbook.create_sheet(0, "Output")
    worksheet1.append(["Job name", "Jenkins-CI plugin"])
    worksheet2 = workbook.create_sheet(1, "Output grouping jobs by plugin")
    worksheet2.append(["Jobs", "Jenkins-CI plugin"])
    worksheet3 = workbook.create_sheet(2, "Plugins installed on Jenkins")
    worksheet3.append(["Plugin name", "Plugin version"])

for root, subFolders, files in os.walk(os.path.join(
        arguments.jenkinshome, "jobs")):
    if 'config.xml' in files:
        with open(os.path.join(root, 'config.xml'), 'r') as fin:
            for lines in fin:
                if 'plugin=' in lines:
                    before_keyword, keyword, after_keyword = lines.partition(
                        'plugin=')
                    jobname = os.path.basename(root)
                    plugin = re.sub(r'"(.+)@([0-9.]+)"/?>\n?',
                                    r'\1 ver. \2', after_keyword)

                    if [jobname, plugin] not in alreadyadded:
                        logging.info("{}: {}".format(jobname, plugin))

                        if arguments.excel:
                            worksheet1.append([jobname, plugin])

                            if plugin not in pluginsalreadyadded:
                                pluginsalreadyadded[plugin] = []

                            pluginsalreadyadded[plugin].append(jobname)

                        alreadyadded.append([jobname, plugin])

for root, subFolder, files in os.walk(os.path.join(
        arguments.jenkinshome, "plugins")):
    if "MANIFEST.MF" in files:
        with open(os.path.join(root, "MANIFEST.MF")) as fon:
            name = None
            version = None
            for line in fon:
                if "Extension-Name: " in line:
                    beforekyw, kyw, name = line.partition("Extension-Name: ")
                    # clean the string
                    name = re.search(r'(\w+)', name).group(0)
                elif "Plugin-Version: " in line:
                    beforekyw, kyw, version = line.partition(
                        "Plugin-Version: ")
                    version = re.sub(r'\n', '', version)
                    # clean the string
                    version = re.search(r'(.+)', version).group(0)
            logging.info("{} ver. {}".format(name, version))

            if arguments.excel:
                worksheet3.append([name, version])

if arguments.excel:
    filedest = os.path.expanduser(arguments.excel)
    filedest = os.path.abspath(filedest)
    path = os.path.dirname(filedest)
    if not os.path.isdir(path):
        os.makedirs(path)

    # write output for worksheet2
    for plugin, jobs in pluginsalreadyadded.iteritems():
        worksheet2.append([" | ".join(jobs), plugin])

    # save the file
    workbook.save(filedest)

这是输出结果:

<(jorge@abril)---(mar may 13 14:30:25)>
[recetario][59] $ ./jenkins-plugins.py --jenkinshome /var/lib/jenkins --excel hoja.xslx
[INFO]: Robert S. - Music metadata from Amazon (Windows build): mercurial ver. 1.50
[INFO]: Robert S. - Music metadata from Amazon (Windows build): jclouds-jenkins ver. 2.5.1
[INFO]: Robert S. - Music metadata from Amazon (Windows build): gcm-notification ver. 1.0
[INFO]: Robert S. - Music metadata from Amazon (Windows build): instant-messaging ver. 1.28
[INFO]: Robert S. - playcomscrap: mercurial ver. 1.50
[INFO]: Robert S. - playcomscrap: shiningpanda ver. 0.20
[INFO]: Robert S. - playcomscrap: gcm-notification ver. 1.0
[INFO]: Robert S. - playcomscrap: instant-messaging ver. 1.28
[INFO]: Robert S. - 419742: mercurial ver. 1.49
[INFO]: Robert S. - Scrap Game Product Information (Windows build): mercurial ver. 1.50
[INFO]: playcomscrap - construye instalable: mercurial ver. 1.50
[INFO]: playcomscrap - construye instalable: gcm-notification ver. 1.0
[INFO]: playcomscrap - construye instalable: instant-messaging ver. 1.28
[INFO]: Robert S. - Scrap Game Product Information (Unit tests): mercurial ver. 1.50
[INFO]: Robert S. - Scrap Game Product Information (Unit tests): shiningpanda ver. 0.20
[INFO]: Danny L. - FLICK 2: mercurial ver. 1.50
[INFO]: jabber ver. 1.25
[INFO]: emotional ver. 1.1
[INFO]: cvs ver. 2.11
[INFO]: mailer ver. 1.8
[INFO]: jclouds ver. 2.5.1
[INFO]: matrix ver. 1.2
[INFO]: python ver. 1.2
[INFO]: compact ver. 1.10
[INFO]: pam ver. 1.1
[INFO]: ldap ver. 1.9
[INFO]: xvfb ver. 1.0.10
[INFO]: mailcommander ver. 1.0.0
[INFO]: ant ver. 1.2
[INFO]: ssh ver. 1.6.1
[INFO]: ssh ver. 1.6
[INFO]: credentials ver. 1.10
[INFO]: jira ver. 1.39
[INFO]: gcm ver. 1.0
[INFO]: libvirt ver. 1.8.4
[INFO]: scm ver. 0.2
[INFO]: subversion ver. 2.3
[INFO]: external ver. 1.2
[INFO]: antisamy ver. 1.1
[INFO]: shiningpanda ver. 0.20
[INFO]: publish ver. 1.11
[INFO]: windows ver. 1.0
[INFO]: maven ver. 2.3
[INFO]: instant ver. 1.28
[INFO]: mercurial ver. 1.50
[INFO]: xvnc ver. 1.14
[INFO]: javadoc ver. 1.1
[INFO]: translation ver. 1.11
[INFO]: matrix ver. 1.2
[INFO]: xunit ver. 1.88
[INFO]: postbuild ver. 1.8
[INFO]: jquery ver. 1.7.2-1

<(jorge@abril)---(mar may 13 14:30:27)>
[recetario][60] $ 

这就是Excel文件的样子:

在这里输入图片描述 在这里输入图片描述 在这里输入图片描述

是的,第二个输出看起来有点丑,但这是因为我没能把单元格的值设置成多行。打开文件时,最后一个工作名称是单元格的值,所以我用|把每个工作名称分开。

使用--help命令来... 嗯,你应该知道这个命令的作用 :)。 你需要安装openpyxl,因为这个模块是写入Excel文件所必需的。

撰写回答