web-dev-qa-db-fra.com

pip 10 et apt: comment éviter les erreurs "Impossible de désinstaller X" pour les paquets distutils

Je traite avec un fichier Dockerfile hérité. Voici une version très simplifiée de ce dont je traite:

FROM ubuntu:14.04

RUN apt-get -y update && apt-get -y install \
    python-pip \
    python-numpy # ...and many other packages

RUN pip install -U pip

RUN pip install -r /tmp/requirements1.txt # includes e.g., numpy==1.13.0
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt

Tout d'abord, plusieurs packages sont installés à l'aide de apt, puis plusieurs packages à l'aide de pip. La version 10 de pip a été publiée et partie de la version } est cette nouvelle restriction:

Suppression de la prise en charge de la désinstallation des projets installés à l'aide de distutils. Les projets installés par distutils n'incluent pas de métadonnées indiquant les fichiers appartenant à cette installation. Il est donc impossible de les désinstaller au lieu de simplement supprimer les métadonnées indiquant qu'elles ont été installées tout en laissant tous les fichiers réels. 

Cela conduit au problème suivant dans ma configuration. Par exemple, la première apt installe python-numpy. Ultérieurement pip tente d'installer une version plus récente de numpy à partir, par exemple, /tmp/requirements1.txt, et tente de désinstaller l'ancienne version, mais en raison de la nouvelle restriction, il ne peut pas supprimer cette version:

Installing collected packages: numpy
  Found existing installation: numpy 1.8.2
Cannot uninstall 'numpy'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

Je sais maintenant qu’il existe plusieurs solutions.

Je ne pouvais pas installer python-numpy à apt. Cependant, cela pose des problèmes car python-numpy installe plusieurs packages différents en tant que configuration requise et je ne sais pas si une autre partie du système repose sur ces packages. Et en réalité, plusieurs packages apt sont installés via le fichier Dockerfile, et chacun de ceux que je supprime semble révéler une autre erreur Cannot uninstall X et supprime un certain nombre d'autres packages, sur lesquels notre application peut s'appuyer ou non. 

Je pourrais aussi utiliser l'option --ignore-installed lorsque j'essaie d'installer pip des choses qui ont déjà été installées via apt, mais là encore, j'ai le même problème de chaque argument --ignore-installed, révélant encore une autre chose à ignorer.

Je pourrais épingler pip à une version plus ancienne qui ne comporte pas cette restriction, mais je ne veux pas rester coincé en utilisant une version obsolète de pip pour toujours. 

Je tourne en rond pour essayer de trouver une bonne solution qui implique des modifications minimes de ce fichier Dockerfile hérité et permet à l'application que nous déployons avec ce fichier de continuer à fonctionner comme avant. Des suggestions sur la façon dont je peux contourner en toute sécurité ce problème de pip 10 ne pouvant pas installer les nouvelles versions de paquets distutils? Je vous remercie!

METTRE À JOUR:

Je ne savais pas que --ignore-installed pouvait être utilisé sans paquet en tant qu'argument pour ignorer tous les paquets installés. J'envisage de savoir si cela pourrait être une bonne option pour moi et en ai posé la question ici .

20
elethan

C’est la solution à laquelle j’ai eu recours et nos applications sont en production sans problèmes depuis près d’un mois avec ce correctif en place:

Tout ce que j'avais à faire était d'ajouter

--ignore-installed

aux lignes pip install de mon fichier de docker qui provoquaient des erreurs. En utilisant le même exemple de dockerfile de ma question initiale, le dockerfile corrigé ressemblerait à quelque chose comme:

FROM ubuntu:14.04

RUN apt-get -y update && apt-get -y install \
    python-pip \
    python-numpy # ...and many other packages

RUN pip install -U pip

RUN pip install -r /tmp/requirements1.txt --ignore-installed # don't try to uninstall existing packages, e.g., numpy
RUN pip install -r /tmp/requirements2.txt
RUN pip install -r /tmp/requirements3.txt

La documentation que j'ai pu trouver pour --ignore-installed n'était pas claire à mon avis (pip install --help indique simplement "Ignorer les paquetages installés (réinstaller à la place)."), Et j'ai posé des questions sur les dangers potentiels de cet indicateur ici , mais il reste encore à obtenir réponse satisfaisante. Cependant, s’il ya des effets secondaires négatifs, notre environnement de production n’en a pas encore vu les effets, et je pense que le risque est faible/nul (du moins cela a été notre expérience). J'ai pu confirmer que dans notre cas, lorsque cet indicateur était utilisé, l'installation existante n'était pas désinstallée, mais que la nouvelle installation était toujours utilisée. 

Mettre à jour:

Je voulais souligner ceci répondre par @ivan_pozdeev. Il fournit des informations que cette réponse ne comprend pas, et il décrit également certains effets secondaires potentiels de ma solution. 

42
elethan

Vous pouvez simplement supprimer numpy manuellement mais conserver les autres dépendances installées par apt. Ensuite, utilisez pip comme auparavant pour installer la dernière version de numpy.

#Manually remove just numpy installed by distutils
RUN rm /usr/lib/python2.7/dist-packages/numpy-1.8.2.Egg-info
RUN rm -r /usr/lib/python2.7/dist-packages/numpy

RUN pip install -U pip
RUN pip install -r /tmp/requirements1.txt

L'emplacement de numpy devrait être le même. Toutefois, si vous souhaitez confirmer l'emplacement, vous pouvez exécuter le conteneur sans exécuter les fichiers requirements.txt, ni exécuter les commandes suivantes dans la console python à l'intérieur du conteneur.

>>> import numpy
>>> print numpy.__file__
/usr/lib/python2.7/dist-packages/numpy/__init__.pyc
0
Moharnab Saikia

C'est ce qui a fonctionné pour moi--

pip install --ignore-installed 

ou Sudo pip install --ignore-installed 

ou (à l'intérieur du cahier juoyter) import sys ! {sys.executable} -m pip install --ignore-installed 

0
Archie Jain