简体   繁体   English

如何使用标准Python库使用file参数触发经过身份验证的Jenkins作业

[英]How to trigger authenticated Jenkins job with file parameter using standard Python library

We are currently triggering Jenkins jobs from a Python script with the help of PycURL. 我们目前在PycURL的帮助下从Python脚本触发Jenkins作业。 We would like, however, to get rid of the PycURL dependency, but have had little success so far. 但是,我们希望摆脱PycURL依赖,但到目前为止收效甚微。 What makes our scenario more complicated is that we need to post a file as a parameter. 使我们的场景更复杂的原因是我们需要将文件作为参数发布。 Our current PycURL logic for posting the request looks as follows: 我们当前用于发布请求的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())

How can we replace this with facilities from the standard Python library? 我们如何用标准Python库中的工具替换它?

We've tried before, but had to give up as we could not see how to upload files successfully, as you can see from my question on that issue . 我们之前已经尝试过,但由于我们无法看到如何成功上传文件而不得不放弃,您可以从我在该问题上的问题中看到。

I found a solution, using the requests and urllib3 libraries. 我找到了一个使用requestsurllib3库的解决方案。 Not entirely standard, but more lightweight than the PycURL dependency. 不完全标准,但比PycURL依赖更轻。 It should be possible to do this directly with requests (avoiding the urllib3 part), but I ran into a bug. 应该可以直接执行请求(避免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()

If you are familiar with python, then you can use the jenkins REST APT python wrapper provided by the official site. 如果你熟悉python,那么你可以使用官方网站提供的jenkins REST APT python包装器。 see this link . 看到这个链接

Trigger a build is unbelievably easy by using this python wrapper. 使用这个python包装器触发构建是非常容易的。 Here is my example: 这是我的例子:

#!/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"})

For those who don't know where to find the token, here is how: 对于那些不知道在哪里找到令牌的人,以下是:

login to jenkins -> click your userid from the top of the webpage -> Configure ->Show API Token... 登录jenkins - >点击网页顶部的用户ID - >配置 - >显示API令牌...

Enjoy it. 好好享受。

We can do it with the help of requests library only. 我们只能在请求库的帮助下完成。

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 if required can be obtained using: 如果需要,可以使用以下方式获得Jekins-Crumb:

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

Probably it can look something like this: 可能它看起来像这样:

url = "https://myjenkins/job/myjob/build"
req = urllib2.Request(url)

auth = 'Basic ' + base64.urlsafe_b64encode("myuser:mypassword")
req.add_header('Authorization', auth)

with open("integration.xml", "r") as f:
  file0 = f.read()
  data = {
            "name": "integration.xml",
            "file0": file0,
            "json": "{'parameter': [{'name': 'integration.xml', 'file': 'file0'}]}",
            "Submit": "Build"
         }
  req.add_data(urllib.urlencode(data))

urllib2.urlopen(req)

Sorry, I don't have installed Jenkins around to test it out. 对不起,我没有安装Jenkins来测试它。

Here is a similar version to aknuds1 answer where test_result is the xml string: 这是aknuds1答案的类似版本,其中test_result是xml字符串:

j_string = "{'parameter': [{'name': 'integration_tests.xml', 'file': 'someFileKey0'}]}"
data = {
          "name": "integration_tests.xml",
          "json": j_string, 
        }
for xml_string in tests.values():
    post_form_result = requests.post('http://jenkins/job/deployment_tests/build',
                                     data=data,
                                     files={'someFileKey0': xml_string})
    print(post_form_result.status_code)

Taking a guess, additional parameters would be passed in as part of the json string array, or additional files, etc. Let me know if this is the case, also, if I find out, i'll update this answer. 猜测,其他参数将作为json字符串数组或其他文件等的一部分传入。如果我发现这种情况,请告诉我,我也会更新此答案。 This solution worked nicely to trigger JUnit tests. 这个解决方案可以很好地触发JUnit测试。

Version: 版:

master* $ pip show requests                                                                                                                                                                      [21:45:05]
Name: requests
Version: 2.12.3
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: me@kennethreitz.com
License: Apache 2.0
Location: /usr/local/lib/python2.7/site-packages

Another Alternative that I used : 我使用的另一种选择:

import requests
import json
url = "https://myjenkins/job/myjob/build"
payload = {'key1': 'value1', 'key2': 'value2'}
resp = requests.post(url, params=payload, auth=("username", "password"),verify=False)
json_data = json.loads(resp.text)

For more details you can refer : Make a Request 有关详细信息,请参阅: 提出申请

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Jenkins-以作业名称为参数的构建触发链 - Jenkins - trigger chain of builds with job names as parameter 如何使用python-jenkins获取詹金斯工作的测试报告 - How to get the test report of a job in Jenkins using python-jenkins 如何使用 Python 的标准库检索 Windows 中的文件详细信息 2 - How can I retrieve a file's details in Windows using the Standard Library for Python 2 如何使用标准 Python 库在 HTTP 上发布文件 - How do I post a file over HTTP using the standard Python library 如何使用Python的标准库zipfile检查条目是文件还是文件夹? - How to check if entry is file or folder using Python's standard library zipfile? 如何使用python的标准库zipfile检查zip文件是否加密? - How to check if a zip file is encrypted using python's standard library zipfile? 如何使用python在Jenkins中提取触发的工作名称 - How to extract triggered job name in Jenkins using python 如何使用Python包JenkinsAPI触发Jenkins构建? - How to trigger Jenkins build using the Python package JenkinsAPI? 如何仅使用python标准库创建excel文件? - how to create a excel file only with python standard library? 如何使用Python使用标准库在内存中构建大型XML文档? - How to build large XML documents in memory with Python using standard library?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM