it-swarm.com.de

pip 10 und apt: So vermeiden Sie Fehler bei der Deinstallation von X-Fehlern für distutils-Pakete

Ich habe es mit einer alten Dockerfile zu tun. Hier ist eine sehr vereinfachte Version von dem, mit dem ich mich befasse:

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

Zuerst werden mehrere Pakete mit apt installiert, und dann werden mehrere Pakete mit pip installiert. pip Version 10 wurde veröffentlicht und Teil der Veröffentlichung ist diese neue Einschränkung:

Unterstützung für die Deinstallation von Projekten, die mit distutils installiert wurden, wurde entfernt. Distutils installierte Projekte enthalten keine Metadaten, aus denen hervorgeht, welche Dateien zu dieser Installation gehören. Daher ist es unmöglich, sie tatsächlich zu deinstallieren, anstatt die Metadaten zu entfernen, die besagen, dass sie installiert wurden, während alle eigentlichen Dateien zurückgelassen werden. 

Dies führt zu folgendem Problem in meinem Setup. Beispielsweise installiert zuerst aptpython-numpy. Später versucht pip, eine neuere Version von numpy von beispielsweise /tmp/requirements1.txt zu installieren, und versucht, die ältere Version zu deinstallieren. Aufgrund der neuen Einschränkung kann diese Version jedoch nicht entfernt werden:

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.

Jetzt weiß ich, dass es an dieser Stelle mehrere Lösungen gibt.

Ich konnte python-numpy nicht durch apt installieren. Dies führt jedoch zu Problemen, da python-numpy einige unterschiedliche Pakete als Anforderungen installiert und ich nicht weiß, ob ein anderer Teil des Systems von diesen Paketen abhängt. In Wirklichkeit gibt es mehrere apt-Pakete, die über die Docker-Datei installiert werden, und jedes, das ich entferne, scheint einen anderen Cannot uninstall X-Fehler aufzudecken, und entfernt eine Reihe anderer Pakete, auf die sich unsere App verlassen kann. 

Ich könnte auch die --ignore-installed-Option verwenden, wenn ich versuche, pip Dinge zu installieren, die bereits durch apt installiert wurden, aber andererseits habe ich dasselbe Problem, wenn jedes --ignore-installed-Argument eine weitere Sache aufdeckt, die noch eine weitere Sache enthüllt, die ignoriert werden muss.

Ich könnte pip an eine ältere Version anhängen, die diese Einschränkung nicht hat, aber ich möchte nicht für immer mit einer veralteten Version von pip hängen bleiben. 

Ich bin im Kreis herumgekommen und habe versucht, eine gute Lösung zu finden, bei der diese veraltete Docker-Datei nur minimal geändert wird und die App, die wir mit dieser Datei bereitstellen, weiterhin so funktioniert, wie sie war. Irgendwelche Vorschläge, wie ich dieses Problem sicher umgehen kann, dass pip 10 nicht in der Lage ist, neuere Versionen von distutils-Paketen zu installieren? Vielen Dank!

AKTUALISIEREN:

Ich wusste nicht, dass --ignore-installed ohne ein Paket als Argument verwendet werden kann, um alle installierten Pakete zu ignorieren. Ich überlege mir, ob dies eine gute Option für mich ist oder nicht, und habe danach hier gefragt.

20
elethan

Dies ist die Lösung, mit der ich am Ende gelaufen bin. Unsere Apps werden seit fast einem Monat ohne Probleme mit dieser Korrektur in der Produktion ausgeführt:

Alles was ich tun musste, war hinzuzufügen

--ignore-installed

an die pip install-Zeilen in meiner Docker-Datei, die zu Fehlern führten. Wenn Sie dasselbe Dockerfile-Beispiel aus meiner ursprünglichen Frage verwenden, würde das feste Dockerfile etwa so aussehen:

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

Die Dokumentation, die ich für --ignore-installed finden konnte, war meiner Meinung nach unklar (pip install --help sagt einfach "Ignoriere die installierten Pakete (stattdessen neu installieren".)), Und ich habe nach den potenziellen Gefahren dieser Flagge hier gefragt, aber noch nicht bekommen befriedigende Antwort. Wenn es jedoch negative Nebenwirkungen gibt, hat unser Produktionsumfeld die Auswirkungen noch nicht erkannt, und ich denke, das Risiko ist gering/keines (zumindest ist dies unsere Erfahrung). Ich konnte bestätigen, dass in unserem Fall bei der Verwendung dieses Flags die vorhandene Installation nicht deinstalliert wurde, dass jedoch die neuere Installation immer verwendet wurde. 

Aktualisieren:

Ich wollte dieses durch @ivan_pozdeev beantworten. Er liefert einige Informationen, die diese Antwort nicht enthält, und er skizziert einige mögliche Nebenwirkungen meiner Lösung. 

42
elethan

Sie können numpy einfach manuell entfernen, die anderen von apt installierten Abhängigkeiten jedoch beibehalten. Verwenden Sie dann pip wie zuvor, um die neueste Version von numpy zu installieren.

#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

Die Position von numpy sollte gleich sein. Wenn Sie den Speicherort jedoch bestätigen möchten, können Sie den Container ausführen, ohne die Datei Requirements.txt auszuführen, und die folgenden Befehle in der Python-Konsole im Container ausgeben.

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

Das hat bei mir funktioniert--

pip install --ignore-installiert 

oder Sudo pip install --ignore-installiert 

oder (in juoyter notebook) import sys ! {sys.executable} -m pip install --ignore-installiert 

0
Archie Jain