Build des releases duniter dans Docker

Tu peux afficher la réponse en ajoutant un print() et voir ce qui est retourné comme réponse…

ligne 42 dans la fonction get_current_message() :

response = urllib.request.urlopen(request) 

print(response)

data = json.load(response)
1 Like

JSON object must be str, not ‘bytes’

signifie que la réponse reçue est du bytes, ce qui signifie qu’il faudrait essayer de convertir en string. Cependant essaie d’afficher pour voir que c’est bien ça.

Car à ma connaissance le script marchait asis !

1 Like

merci @vit je viens d’ajouter un print de la réponse et de pusher un nouveau tag on vas bien voir si l’hypothèse de @sveyret est la bonne :slight_smile:

@florck @sveyret @vit , voilà le print de la réponse de l’api :

<http.client.HTTPResponse object at 0x7f4aff1f7c18>

@florck peut tu retry ton job qui avait marché debut décembre pour voir si c’est une mise a jours de l’api gitlab qui est en cause ?

On ne peut pas afficher response directement car il s’agit d’un flux. D’ailleurs, si c’était une chaine, on aurait utilisé json.loads (avec un s à la fin) et non json.load. As-tu vérifié si ton token était bien renseigné et si tu n’avais pas une erreur 401 depuis l’image Docker ?

J’ai revérifier et copier coller le contenu de la variable dans ma console la requête curl passe, et si je change 1 seul caractère j’ai effectivement une erreur 401. Bref, je suis certain à 100% que le token est bon et la variable aussi, je pense que le problème viens de l’environnement d’exécution, je ne sais pas dans quel image docker @florck a exécuté son script avec succès, car c’est un runner qui tournais sur son pc perso.

J’ai utiliser l’image tensorflow/tensorflow:latest-py3 pour éviter d’avoir a créer une image spécifique juste pour exécuter un script… mais peut être que le problème viens de là.

On vas être obligé de créer une image spécifique juste pour le job de publication des releases dans la tag page ? Je trouve ça franchement très lourd !

@florck peut tu nous partager ton dockerfile de ton runner flork-demo que l’on voit si le problème viens de là !

1 Like

en fait, cette démo se joue pas dans docker, donc non, c’est pas ça. Ce que tu affiches est un objet httpresponse, il faudrait réussir à lire ce qu’il à a dedans…

À priori, il faudrait exécuter response.read().decode('utf-8').

1 Like

Tu peux créer un petit script de test, comme test_request.py, avec dedans :

#!/usr/bin/env python3

import urllib.request

url = "https://g1-test.duniter.org/network/peers"

request = urllib.request.Request(url)
response = urllib.request.urlopen(request)

print('status: %s' % response.status)
print('headers:', response.headers)
print('body:' + response.read().decode('utf-8'))

Remplace l’url par celle qui pose problème et analyse la réponse… Hope it helps…

2 Likes

merci pour ton aide @vit, ton script s’éxécute avec succès donc le problème ne viens pas de l’image docker que j’ai choisi, j’ai ajouté ton code de print au script de @florck et voila ce que j’obtiens :

 $ python3 .gitlab/releaser.py
status: 200
headers: Server: nginx/1.12.1
Date: Mon, 15 Jan 2018 14:47:45 GMT
Content-Type: application/json
Content-Length: 501
Connection: close
Cache-Control: max-age=0, private, must-revalidate
Etag: W/"1c9722cad0d3c3072036eab7359b8fbe"
Vary: Origin
X-Frame-Options: SAMEORIGIN
X-Request-Id: ab86d658-b1aa-4d2f-b03c-47daa40c6a9c
X-Runtime: 0.255735
Strict-Transport-Security: max-age=31536000


Traceback (most recent call last):
  File ".gitlab/releaser.py", line 161, in <module>
    main()
  File ".gitlab/releaser.py", line 157, in main
    exists_release, current_message = get_current_message()
  File ".gitlab/releaser.py", line 44, in get_current_message
    print('body:' + response.read().decode('utf-8'))
UnicodeEncodeError: 'ascii' codec can't encode character '\xc9' in position 292: ordinal not in range(128)
ERROR: Job failed: exit code 1

La réponse à le statut 200, le problème ne viens donc pas de la requête ni du token @sveyret , c’est bien un problème d’utilisation de la réponse par le script python, mais comme je ne connais pas du tout python ça irai bien plus vite si l’un d’entre vous s’en chargeai car là ça fait déjà presque 1semaine qu’un bloque juste sur le job de publication de la tagpage et ça commence franchement a me gaver …

Bon avec @vit nous avons avancer, on pense que le souci viens d’un accent dans le nom de mon profil, ce qui expliquerai que le script d"origine est marché dans le cas de florck (pas d’accent dans son profil).

De toute façon comme l’authentification se fait en personnal access token c’est plus propre de créer un user dédié pour ce job, j’ai donc créer un user releaser-duniter puis commiter et tagger avec ce user, il semble toujours y avoir un problème mais uniquement lié au code de print, donc si ça se trouve ça vas fonctionner en le supprimant, je vais tester ça (et c’est parti pour un ième tag de test :stuck_out_tongue: )

$ python3 .gitlab/releaser.py
status: 200
headers: Server: nginx/1.12.1
Date: Mon, 15 Jan 2018 15:31:18 GMT
Content-Type: application/json
Content-Length: 519
Connection: close
Cache-Control: max-age=0, private, must-revalidate
Etag: W/"c4724aae611103f9cf00abdce9785cf8"
Vary: Origin
X-Frame-Options: SAMEORIGIN
X-Request-Id: 513d8c00-0f5f-4a9f-95f6-df3efd4b2e16
X-Runtime: 0.243020
Strict-Transport-Security: max-age=31536000


Traceback (most recent call last):
  File ".gitlab/releaser.py", line 161, in <module>
    main()
  File ".gitlab/releaser.py", line 157, in main
    exists_release, current_message = get_current_message()
  File ".gitlab/releaser.py", line 44, in get_current_message
    print('body:' + response.read())
TypeError: Can't convert 'bytes' object to str implicitly
ERROR: Job failed: exit code 1
1 Like

En tous cas, il semble que c’est la réponse qui n’est pas vraiment en UTF-8. Étrange.

C’est peut-être le + qui ne fonctionne pas tel quel, il faudrait essayer :

print(u'body:' + response.read().decode('utf-8'))

Note le u devant ‘body’.

Bon je crois que python se fou de ma gueule, voici 3 variantes du code et l’erreur générée :

data = json.load(response)
TypeError: the JSON object must be str, not 'bytes'

data = json.load(response.read())
AttributeError: 'str' object has no attribute 'read'

data = json.load(response.decode())
AttributeError: 'HTTPResponse' object has no attribute 'decode'

Je précise qu’on est ici dans un test sans accent nul part et que la réponse JSON est correctement printée par le script, la preuve : https://git.duniter.org/nodes/typescript/duniter/-/jobs/1340

La première erreur est normale.
json.load analyse l’objet (ici de la classe HTTPResponse) comme une string, celui-ci réagit alors en renvoyant une representation en bytes. Donc la première erreur est “normale”.

La seconde erreur n’est pas normale. response contient un objet de la classe HTTPResponse dont le body est extrait comme un fichier avec la méthode read(). Pourquoi la variable response contient une string cette fois là… Mystère.

La dernière erreur est normale.
La variable réponse est un objet et ne peut pas être traité comme une chaine de bytes avec decode().

response doit être traitée comme suit si la variable contient bien un objet de la classe HTTPResponse :

response_body = response.read().decode()
data = json.load(response_body)

Normalement (l’informatique étant une activité hautement incantatoire).

[EDIT]
J’ai compris !
Faire un response.read() vide le buffer de la réponse, ou amène le pointeur à la fin. bref, on ne peut faire le response.read() deux fois. Ce qui explique le changement de type de la variable selon que l’on fait un read() avant ou pas…

Si response_body est une chaine, alors ce n’est pas load qu’il faut appeler mais :

json.loads(response_body) 

(avec un s à la fin du nom de fonction).

1 Like

Sinon il y a ce code d’expert qui fonctionne :

strJSON = '' + response.read().decode('utf-8')
data = json.loads(strJSON)
2 Likes

Bon la saga continue, merci beaucoup à @vit et @sveyret le problème de typage est enfin résolu, mais il y a encore un autre problème plus loin dans le script :joy:

Le problème venait du fait que chez @florck qui utilisait l’objet comme une string, python le convertit en renvoyant la méthode repr de l’objet (une représentation), c’est automatique. hors dans l’image docker que j’utilise, cette conversion automatique ne se fait pas, ça doit être une version de python un pue plus stricte.

le code qui fonctionne :
response_data = response.read().decode()
data = json.loads(response_data)

Problème suivant :

$ python3 .gitlab/releaser.py
Traceback (most recent call last):
  File ".gitlab/releaser.py", line 153, in <module>
    main()
  File ".gitlab/releaser.py", line 150, in main
    compiled_message = build_compiled_message(current_message)
  File ".gitlab/releaser.py", line 92, in build_compiled_message
    'size': get_artifact_weight(artifact),
  File ".gitlab/releaser.py", line 72, in get_artifact_weight
    size = os.path.getsize(location)
  File "/usr/lib/python3.5/genericpath.py", line 50, in getsize
    return os.stat(filename).st_size
FileNotFoundError: [Errno 2] No such file or directory: 'duniter-desktop-0.99.19-linux-x64.deb'
ERROR: Job failed: exit code 1

je pense que le souci viens de la façon dont ce font les build, qui est différente de ce a quoi s’attendait le script de @florck a l’origine. En effet le script de build fourni un .zip , il faudrait donc soit :

  • changer le script de build pour fournir 3 artifacts différents non zippés (je ne sais pas si ça viens de la config gitlab-ci ou du script de build de @sveyret ou un peu des deux)
  • soit dézipper l’archive au sein du script python

je vais me pencher sur la 1ère option :slight_smile:

Je pense qu’il te manque une entrée dependencies dans le gitlab-ci.yml pour transmettre les fichiers créés par l’étape build. Je vais regarder.

1 Like

Non, à priori, ce n’est pas utile si les stage se suivent :

https://docs.gitlab.com/ce/ci/yaml/README.html#dependencies

Par contre, j’ai vu que tu avais mis un expires_in pour la partie deploy. Est-ce que c’est normal ?

Dans le gitlab_ci utiliser par @florck il n’y a pas d’entrée dependencies, en revanche il explicitait le chemin de chaque artifact : .gitlab-ci.yml · master · florck / demo-runner-perso · GitLab

j’ai donc fait pareil, le test est en cours : explain the path to each artifacts (ec96180a) · Commits · nodes / typescript / duniter · GitLab

Oui en fait on peut les keep manuellement si elles sont bonnes, mais ça ne sert a rien de laisser des pre-releases qui s’avérerait contenir un bug critique par exemple ou etre cassés

2 Likes