如何使用标准Python库触发带文件参数的认证Jenkins任务

15 投票
7 回答
21454 浏览
提问于 2025-04-17 07:43

我们现在是通过一个Python脚本来触发Jenkins的任务,使用的是PycURL这个库。不过,我们想要去掉对PycURL的依赖,但到目前为止还没什么成功。让事情变得更复杂的是,我们需要把一个文件作为参数上传。我们现在用PycURL发送请求的代码大概是这样的:

url = "https://myjenkins/job/myjob/build"
with contextlib.closing(pycurl.Curl()) as curl:
    curl.setopt(pycurl.URL, url)
    curl.setopt(pycurl.USERPWD, "myuser:mypassword")
    curl.setopt(pycurl.SSL_VERIFYPEER, False)
    curl.setopt(pycurl.SSL_VERIFYHOST, False)
    curl.setopt(pycurl.FAILONERROR, True)
    data = [
            ("name", "integration.xml"),
            ("file0", (pycurl.FORM_FILE, "integration.xml")),
            ("json", "{'parameter': [{'name': 'integration.xml', 'file': 'file0'}]}"),
            ("Submit", "Build"),
            ]
    curl.setopt(pycurl.HTTPPOST, data)
    try:
        curl.perform()
    except pycurl.error, err:
        raise JenkinsTriggerError(curl.errstr())

我们想知道怎么用Python标准库里的工具来替代这个方法。

我们之前尝试过,但因为不知道怎么成功上传文件,所以最后放弃了。你可以在我关于这个问题的提问中看到相关内容。

7 个回答

6

如果你对Python有点了解,可以使用官方提供的Jenkins REST API的Python封装库。可以查看这个链接

通过这个Python封装库触发构建非常简单。下面是我的一个例子:

#!/usr/bin/python
import jenkins

if __name == "main":
    j = jenkins.Jenkins(jenkins_server_url, username="youruserid", password="yourtoken")
    j.build_job(yourjobname,{'param1': 'test value 1', 'param2': 'test value 2'},
                    {'token': "yourtoken"})

对于那些不知道在哪里找到令牌的人,这里有个方法:

登录Jenkins -> 点击网页顶部的你的用户名 -> 配置 -> 显示API令牌...

祝你使用愉快。

10

我们可以仅通过使用requests库来完成这个任务。

import requests

payload = ( ('file0', open("FILE_LOCATION_ON_LOCAL_MACHINE", "rb")), 
            ('json', '{ "parameter": [ { 
                                         "name":"FILE_LOCATION_AS_SET_IN_JENKINS", 
                                         "file":"file0" }]}' ))

resp = requests.post("JENKINS_URL/job/JOB_NAME/build", 
                   auth=('username','password'), 
                   headers={"Jenkins-Crumb":"9e1cf46405223fb634323442a55f4412"}, 
                   files=payload )

如果需要的话,可以通过以下方式获取Jekins-Crumb:

requests.get('http://username:password@JENKINS_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
6

我找到了一种解决办法,使用了requestsurllib3这两个库。虽然这不是完全标准的做法,但比起依赖PycURL来说,它更轻量一些。其实可以直接用requests来完成这个任务(这样就不用urllib3了),不过我遇到了一个小错误。

import urllib3, requests, json

url = "https://myjenkins.com/job/myjob"

params = {"parameter": [
    {"name": "integration.xml", "file": "file0"},
    ]}
with open("integration.xml", "rb") as f:
    file_data = f.read()
data, content_type = urllib3.encode_multipart_formdata([
    ("file0", (f.name, file_data)),
    ("json", json.dumps(params)),
    ("Submit", "Build"),
    ])
resp = requests.post(url, auth=("myuser", "mypassword"), data=data,
        headers={"content-type": content_type}, verify=False)
resp.raise_for_status()

撰写回答