2011-12-05 7 views
12

Attualmente stiamo attivando i lavori Jenkins da uno script Python con l'aiuto di PycURL. Vorremmo, tuttavia, sbarazzarci della dipendenza da PycURL, ma finora abbiamo avuto scarso successo. Ciò che rende il nostro scenario più complicato è che dobbiamo pubblicare un file come parametro. La nostra logica pycurl corrente per l'invio della richiesta appare come segue:Come attivare il lavoro Jenkins autenticato con parametro file usando la libreria standard Python

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

Come possiamo sostituire questo con servizi di libreria standard di Python?

Abbiamo provato prima, ma abbiamo dovuto rinunciare perché non abbiamo potuto vedere come caricare i file con successo, come si può vedere dal my question on that issue.

+0

Sembra che tu stia usando 'https'. Attenzione che 'httplib' e' urllib2' non verificano il certificato del server durante la connessione a un sito Web HTTPS (consultare la documentazione ufficiale), quindi non sarà in grado di stabilire la connessione in modo sicuro. (Puoi aggirare il problema avvolgendo la connessione 'httplib' usando il modulo' ssl'.) – Bruno

+0

Se guardi il mio codice, vedrai che sto dicendo a cURL di ignorare il certificato HTTPS :) È un sito intranet, quindi non dovrebbe importare. – aknuds1

+0

Perché si desidera utilizzare urllib2/httplib su pycURL? – codersofthedark

risposta

6

Ho trovato una soluzione, utilizzando le librerie requests e urllib3. Non del tutto standard, ma più leggero della dipendenza PycURL. Dovrebbe essere possibile farlo direttamente con le richieste (evitando la parte urllib3), ma mi sono imbattuto in un bug.

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

Quindi, se la compilazione richiede un token, verrà aggiunta insieme ai parametri? L'ho provato e non sembra che venga generato – AsadSMalik

+0

* non sembra costruire con il parametro impostato – AsadSMalik

+0

@ Joiya550 Dovresti replicare come i token vengono normalmente inviati (ad esempio nel browser). – aknuds1

1

Probabilmente può essere simile a questa:

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) 

Mi dispiace, non è installato sul Jenkins giro di provarlo.

+0

Testato ora e non funziona. – aknuds1

5

Se si ha familiarità con python, quindi è possibile utilizzare il Jenkins REST APT pitone involucro fornito dal sito ufficiale. see this link.

Attivare una build è incredibilmente facile utilizzando questo wrapper python. Qui è il mio esempio:

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

Per coloro che non sanno dove trovare il token, ecco come:

login per Jenkins -> clicca il tuo userid dalla parte superiore della pagina web - > Configura -> Mostra token API ...

Divertiti.

+1

Non include tuttavia un parametro file. – aknuds1

-1

un'altra alternativa che ho usato:

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) 

Per maggiori dettagli è possibile fare riferimento: Make a Request

+0

Tuttavia, non mostra come pubblicare un file. – aknuds1

+0

@ aknuds1 Risposta migliorata alla richiesta di post con parametri. Spero che questo risolva la tua domanda. –

+0

Mostra comunque come pubblicare un file? Dai un'occhiata alla mia domanda e rispondi per riferimento. – aknuds1

0

Ecco una versione simile a aknuds1 risposta dove test_result è la stringa 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) 

In base a un'ipotesi, i parametri aggiuntivi verranno passati come parte dell'array json string, o file aggiuntivi, ecc. Fammi sapere se questo è il caso, inoltre, se lo scoprirò, aggiornerò questa risposta. Questa soluzione ha funzionato bene per attivare i test JUnit.

Versione:

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 
3

Possiamo farlo con l'aiuto di richieste unica biblioteca.

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 se necessario può essere ottenuto con:

requests.get('http://username:[email protected]_URL/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')