Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

Я нашел решение, используя requests и 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()

Ответ 2

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

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

Наслаждайтесь этим.

Ответ 3

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

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:[email protected]_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')

Ответ 4

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

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)

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

Ответ 5

Вот аналогичная версия для ответа 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 string, или дополнительные файлы и т.д. Сообщите мне, если это так, также если я узнаю, я обновлю этот ответ. Это решение отлично работало для запуска тестов 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: [email protected]
License: Apache 2.0
Location: /usr/local/lib/python2.7/site-packages

Ответ 6

@AsadSMalik:

Пожалуйста, опубликуйте решение, которое в конечном итоге работает

Ответ 7

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

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)

Для получения дополнительной информации вы можете обратиться: Сделать запрос