Obecnie wywołujemy Jenkins Jobs z skryptu Pythona za pomocą Pycurl. Chcielibyśmy jednak pozbyć się zależności Pycurl, ale do tej pory miały niewielki sukces. Co sprawia, że nasz scenariusz jest bardziej skomplikowany, jest to, że musimy opublikować plik jako parametr. Nasza aktualna logika Pycurl do publikowania żądania wygląda następująco:

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

Jak możemy to zastąpić obiektami ze standardowej biblioteki Python?

Próbowaliśmy wcześniej, ale musieliśmy zrezygnować, ponieważ nie widzieliśmy, jak przesyłać pliki z powodzeniem, jak widać z Moje pytanie na ten problem.

13
aknuds1 5 grudzień 2011, 14:48

6 odpowiedzi

Najlepsza odpowiedź

Znalazłem rozwiązanie, za pomocą żądania i Biblioteki Urllib3. Nie jest całkowicie standardowy, ale bardziej lekki niż zależność Pycurl. Powinno to zrobić bezpośrednio z żądaniami (unikając części Urllib3), ale wpadłem w błąd.

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()
6
aknuds1 18 kwiecień 2014, 17:47

Możemy to zrobić tylko przy pomocy biblioteki żądań.

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 )

Jenkins-Crucia, jeśli wymagane można uzyskać za pomocą:

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

Prawdopodobnie może wyglądać na coś takiego:

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)

Przepraszam, nie zainstalowałem Jenkinów, aby to przetestować.

1
Ivan Blinkov 24 kwiecień 2012, 11:34

Kolejną alternatywą, którą użyłem:

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)

Aby uzyskać więcej informacji, możesz odnosić się: Zrób wniosek.

0
Kamesh Jungi 12 kwiecień 2016, 07:28

Oto podobna wersja do AKNUDS1 Odpowiedź, gdzie test_result jest ciągiem 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)

Zgadnij, że dodatkowe parametry zostaną przekazane jako część tablicy sznurkowej JSON lub dodatkowych plików itp. Daj mi znać, jeśli tak jest, jeśli się dowiem, zaktualizuję tę odpowiedź. To rozwiązanie ładnie pracował do wyzwalania testów Junit.

Wersja:

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
jmunsch 7 grudzień 2016, 05:55

Jeśli jesteś zaznajomiony z Pythonem, możesz użyć Jenkins Reped Apt Python Wrapper dostarczony przez oficjalną stronę. Zobacz ten link.

Wyzwalacz kompilacja jest niewiarygodnie łatwa, używając tego opakowania Pythona. Oto mój przykład:

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

Dla tych, którzy nie wiedzą, gdzie znaleźć token, oto jak:

Zaloguj się do Jenkins -> Kliknij swój identyfikator użytkownika z góry strony internetowej -> Skonfiguruj -> Pokaż token API ...

Ciesz się.

7
mainframer 21 maj 2015, 09:48