libgit2 / libgit2/pygit2

KeypairFromAgent throws fetch into an infinite loop

Abierto
#953 0 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Lenguaje dominante
Python
Estrellas
1.7k
Forks
408
Merge medio
2 d 57 min
PR fusionados (30 d)
7

Descripción

I'm not sure I'm using it right, but the following code throws git_remote_fetch into some sort of infinite loop in case the agent can't find an appropriate key.

import pygit2

class MyCallbacks(pygit2.RemoteCallbacks):
    def credentials(self, url, username_from_url, allowed_types):
        # print('Credentials callback called')
        return pygit2.KeypairFromAgent(username_from_url)

repo = pygit2.Repository('foo')
repo.remotes['origin'].fetch(callbacks=MyCallbacks())
print("OK")

Here's an example:

$ git clone git@<some-ssh-repository> foo
Cloning into 'foo'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
$ python3 test.py  # Using my regular ssh agent which has the correct key
OK
$ eval $(ssh-agent)  # Create a new ssh-agent with no key and update env variables
$ python3 test.py  # Never returns...

If I uncomment the print statement in the python snippet above, I can see that my callback is called over and over.

There's one more thing that is odd but might help: when I interrupt the script with ctrl-c, I don't always get the same traceback. In the second case bellow it seems that the "correct" exception (_pygit2.GitError: callback failed to initialize SSH credentials) is raised at some point but just doesn't reach my code:

❯❯❯ python3 test.py
# ^C
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    repo.remotes['origin'].fetch(callbacks=MyCallbacks())
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 406, in fetch
    err = C.git_remote_fetch(self._remote, arr, fetch_opts, to_bytes(message))
KeyboardInterrupt
❯❯❯ python3 test.py
# ^C
From cffi callback <function RemoteCallbacks._credentials_cb at 0x7f5e027700d0>:
Traceback (most recent call last):
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 304, in _credentials_cb
    ccred = get_credentials(credentials, url, username, allowed)
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 515, in get_credentials
    if pubkey is None and privkey is None:
KeyboardInterrupt
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    repo.remotes['origin'].fetch(callbacks=MyCallbacks())
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 409, in fetch
    check_error(err)
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/errors.py", line 64, in check_error
    raise GitError(message)
_pygit2.GitError: callback failed to initialize SSH credentials

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con las rutas de remote.py que aparecen en el traceback, especialmente RemoteCallbacks._credentials_cb y get_credentials. Reproduce el fetch con un ssh-agent que no contenga ninguna clave y, a continuación, sigue el callback y el manejo del error de credenciales. Se considera terminado cuando la búsqueda fallida de credenciales deja de reintentarse y el GitError esperado llega al llamador.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
git, python
Área
tooling
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
35/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.