Как запустить аутентифицированное задание Jenkins с параметром файла, используя стандартную библиотеку Python - PullRequest
12 голосов
/ 05 декабря 2011

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

6 голосов
/ 09 августа 2012

Я нашел решение, используя запросы и 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()
5 голосов
/ 04 марта 2017

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

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)')
5 голосов
/ 21 мая 2015

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

Запустить сборку невероятно легко с помощью этой оболочки 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 ...

Наслаждайтесь.

1 голос
/ 24 апреля 2012

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

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, чтобы протестировать его.

0 голосов
/ 07 декабря 2016

Вот версия, аналогичная ответу 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
0 голосов
/ 12 апреля 2016

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

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)

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

...