Fabric: c. poner confusión sobre una cadena frente a un objeto similar a un archivo en local

Creado en 14 may. 2018  ·  6Comentarios  ·  Fuente: fabric/fabric

De acuerdo con los documentos transfer.put () , debería poder proporcionar una ruta local a un archivo (como una cadena) o un objeto similar a un archivo.

Cuando utilizo la primera (cadena), puedo especificar en la ruta remote solo el directorio de destino. Esto se usa en algunos ejemplos :

c.put('myfiles.tgz', '/opt/mydata')

Pero cuando trato de hacer lo mismo ( c.put('file.txt', '/home/me/dir') , siempre termino con IOError: Failure , porque en realidad se está comportando como si la ruta local fuera un objeto similar a un archivo y no una cuerda.

Falla específicamente en paramiko.transport.sftp.sftp._log: [chan 0] open('/home/me/dir', 'wb')

La solución es proporcionar siempre la ruta completa, p. Ej.

c.put('file.txt', '/home/me/dir/file.txt')

Pero eso es inconsistente con los documentos y ejemplos.

Finalmente, tener que proporcionar la ruta completa a $HOME es menos que ideal, pero parece haber un problema para eso ya # 1653

  • Probado en Windows 10
  • Tejido 2.0.0
  • Paramiko 2.4.1
  • Invocar 1.0.0
Bug Wart put()/get()

Todos 6 comentarios

¿Alguna actualización sobre esto? Connection.put con remote como cadena de ruta de directorio actualmente genera IOError .

(¡También gracias por todo el trabajo en Fabric et al!)

Tejido 2.1.3
Paramiko 2.4.1
Invocar 1.0.0

Suena como un error legítimo, lo veré más tarde. Parches (¡y pruebas! Ya que todos pasaron :( lo que implica que nos faltan algunos ...) bienvenidos.

Mirando esto ahora, en realidad no estoy seguro de que el problema sea la suposición de FLO, creo que en cambio es simplemente una falta directa de implementar la ruta remota correcta munging; en otras palabras, le estamos pidiendo al servidor SFTP que abra el directorio como un archivo para escribir, en lugar de agregar el nombre base del archivo local a la ruta del directorio remoto.

Registro de depuración parcial del final de Fabric:

invoke.transfer.put: Massaged relative local path 'setup.py' into '/Users/jforcier/Code/oss/fabric/setup.py'
invoke.transfer.put: Uploading '/Users/jforcier/Code/oss/fabric/setup.py' to '/Users/jforcier/tmp/'
paramiko.transport.sftp.sftp._log: [chan 2] open(b'/Users/jforcier/tmp/', 'wb')

Luego, parte del rastreo muestra que estamos lanzando esa ruta de directorio a CMD_OPEN, en sftp_client.py :

t, msg = self._request(CMD_OPEN, filename, imode, attrblock)

Lo que eventualmente golpea el mismo manejo de errores de archivo / clase en torno a lo que el servidor SFTP dijo que estaba mal con la operación de IO (razón por la cual es solo "Fallo" porque, por supuesto, es ... AFAIK, eso es culpa de OpenSSH).


De todos modos, es hora de escribir algunas pruebas para probar esto y luego averiguar si es un error lógico (pensé que _ estábamos_ construyendo una ruta adjunta en algún momento) o una pieza de funcionalidad que faltaba directamente.

De acuerdo, no, todo lo relacionado con rutas remotas vacías o relativas, no hay verificación del directorio is.

Mientras estoy aquí, me pregunto cómo manejar los FLO también, en el caso de que la ruta remota sea un directorio.

En la v1, observamos el atributo .name de FLO porque es

De todos modos, aquí en la v2 tenemos la oportunidad de abordar eso en serio, o simplemente lanzar una excepción explícita que diga "oye, necesitas dar una ruta de archivo remoto que no sea de directorio para estos". Probablemente ambos, ya que no todos los FLO tienen necesariamente el atributo de nombre de todos modos.

De acuerdo, todo está arreglado, saldrá en la próxima versión de corrección de errores 🎉

¿Fue útil esta página
0 / 5 - 0 calificaciones