Как запустить аутентифицированное задание Дженкинса с параметром файла, используя стандартную библиотеку Python

в настоящее время мы запускаем задания Дженкинса из скрипта Python с помощью 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?

мы пробовали раньше, но было сдаваться, мы не могли видеть, как успешно загружать файлы, как вы можете видеть из мой вопрос по этому вопросу.

6 ответов


Я нашел решение, используя запросы и urllib3 библиотеки. Не совсем стандартная, но более легкая, чем зависимость от PycURL. Это должно быть возможно сделать непосредственно с запросами (избегая части 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()

Если вы знакомы с python, то вы можете использовать оболочку Jenkins REST APT python, предоставленную официальным сайтом. ссылка.

Trigger сборка невероятно проста, используя эту оболочку 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 Знак...

понравится.


мы можем сделать это только с помощью библиотеки запросов.

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)')

вероятно, это может выглядеть примерно так:

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)

Извините, я не установил Дженкинса, чтобы проверить его.


вот аналогичная версия ответа 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)

предположим, дополнительные параметры будут переданы как часть массива строк json или дополнительных файлов и т. д. Дайте мне знать, если это так, Также, если я узнаю, я обновлю этот ответ. Это решение отлично сработало для запуска тестов JUnit.

версия:

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

другая альтернатива, которую я использовал:

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)

для больше деталей вы можете сослаться:оформить заявку