Fabric: c.put confusion à propos d'une chaîne par rapport à un objet de type fichier en local

Créé le 14 mai 2018  ·  6Commentaires  ·  Source: fabric/fabric

Selon transfer.put() docs , je devrais être en mesure de fournir soit un chemin local vers un fichier (sous forme de chaîne), soit un objet de type fichier.

Lors de l'utilisation du premier (chaîne), je peux spécifier dans le chemin remote uniquement le répertoire cible. Ceci est utilisé dans quelques exemples :

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

Mais quand j'essaie de faire la même chose ( c.put('file.txt', '/home/me/dir') , je me retrouve toujours avec IOError: Failure , car il se comporte en fait comme si le chemin local était un objet de type fichier et pas une chaîne.

Il échoue spécifiquement sur paramiko.transport.sftp.sftp._log: [chan 0] open('/home/me/dir', 'wb')

La solution est de toujours fournir le chemin complet, par exemple

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

Mais cela est incompatible avec les documents et les exemples.

Enfin, devoir fournir le chemin complet vers $HOME est loin d'être idéal, mais il semble déjà y avoir un problème pour cela #1653

  • Testé sous Windows 10
  • Tissu 2.0.0
  • Paramiko 2.4.1
  • Invoquer 1.0.0
Bug Wart put()/get()

Tous les 6 commentaires

Des mises à jour à ce sujet ? Connection.put avec remote comme chaîne de chemin de répertoire lève actuellement IOError .

(Merci aussi pour tout le travail sur Fabric et al !)

Tissu 2.1.3
Paramiko 2.4.1
Invoquer 1.0.0

Cela ressemble à un bug légitime, je vais y jeter un œil plus tard. Patchs (et tests ! puisque les nôtres sont tous passés :( ce qui implique qu'il nous en manque quelques-uns...) bienvenus.

En regardant cela maintenant, je ne suis pas vraiment sûr que le problème soit l'hypothèse de FLO, je pense qu'il s'agit plutôt d'un simple manque de mise en œuvre d'un chemin distant correct - en d'autres termes, nous demandons au serveur SFTP d'ouvrir le répertoire comme un fichier à écrire, au lieu d'ajouter le nom de base du fichier local au chemin du répertoire distant.

Journal de débogage partiel 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')

Ensuite, une partie du traçage montre que nous lançons ce chemin de répertoire dans CMD_OPEN, dans sftp_client.py :

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

Ce qui finit par toucher le même traitement d'erreur de fichier/classe autour de ce que le serveur SFTP a dit était faux avec l'opération d'E/S (c'est pourquoi c'est juste "Échec" parce que bien sûr c'est... AFAIK c'est la faute d'OpenSSH.)


Quoi qu'il en soit, il est temps d'écrire des tests pour le prouver, puis de déterminer s'il s'agit d'une logique (je pensais que nous construisions un chemin ajouté à un moment donné) ou d'une fonctionnalité manquante.

OK, non, tout le munging se fait autour de chemins distants vides ou relatifs, il n'y a pas de vérification du répertoire is.

Pendant que je suis ici, je me demande aussi comment gérer les FLO, dans le cas où le chemin distant est un répertoire.

Dans la v1, nous avons examiné l'attribut .name des FLO car cela fait

Quoi qu'il en soit, donc ici, dans la v2, nous avons la possibilité de résoudre ce problème pour de vrai, ou de simplement lancer une exception explicite disant "whoa hey vous devez donner un chemin de fichier distant non-répertoire pour ceux-ci". Probablement les deux, car tous les FLO n'ont pas nécessairement l'attribut name de toute façon.

OK, tout est corrigé, ce sera dans la prochaine version de correction de bugs 🎉

Cette page vous a été utile?
0 / 5 - 0 notes