it-swarm-eu.dev

pip 10 a apt: jak se vyhnout chybám "Nelze odinstalovat X" pro balíky distutils

Zabývám se dědičným souborem Dockerfile. Zde je velmi zjednodušená verze toho, co se zabývám:

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

Nejprve je několik balíčků instalováno pomocí apt a několik balíčků je instalováno pomocí pip. pip verze 10 byla vydána a část tohoto vydání je toto nové omezení:

Byla odstraněna podpora pro odinstalaci projektů, které byly nainstalovány pomocí distutils. instalované projekty distutils neobsahují metadata označující, které soubory patří k této instalaci, a proto je nemůžete skutečně odinstalovat, nýbrž pouze odstranit metadata s tím, že byly nainstalovány, zatímco všechny skutečné soubory zůstaly v pozadí. 

To vede k následujícímu problému v mém nastavení. Například první apt nainstaluje python-numpy. Později se pip pokouší nainstalovat novější verzi numpy z např. /tmp/requirements1.txt a pokouší se odinstalovat starší verzi, ale kvůli novému omezení tuto verzi nemůže odstranit:

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.

Nyní vím, že v tomto bodě existuje několik řešení.

Nemohu nainstalovat python-numpy prostřednictvím apt. To však způsobuje problémy, protože python-numpy nainstaluje několik různých balíčků jako požadavky a já nevím, zda se na tyto balíčky spoléhá jiná část systému. A ve skutečnosti existuje několik balíčků apt instalovaných přes Dockerfile a každý z nich, který jsem odstranil, odhaluje další chybu Cannot uninstall X a odstraňuje s sebou řadu dalších balíčků, na které se naše aplikace může nebo nemusí spoléhat. 

Mohu také použít volbu --ignore-installed, když se snažím pip instalovat věci, které již byly nainstalovány prostřednictvím apt, ale pak mám opět stejný problém s každým argumentem --ignore-installed, který odhaluje další věc, kterou je třeba ignorovat.

Mohl bych připojit pip na starší verzi, která toto omezení nemá, ale nechci být navždy zaseknuta pomocí zastaralé verze pip

Chodím v kruzích a snažím se přijít s dobrým řešením, které zahrnuje minimální změny tohoto dědičného souboru Dockerfile a umožňuje aplikaci, kterou tento soubor implementujeme, aby i nadále fungovala tak, jak byla. Jakékoli návrhy týkající se toho, jak mohu bezpečně obejít tento problém pip 10, protože nejsou schopny instalovat novější verze balíčků distutils? Děkuji!

AKTUALIZACE:

Neuvědomil jsem si, že --ignore-installed by mohlo být použito bez balíčku jako argument pro ignorování všech nainstalovaných balíčků. Uvažuji o tom, zda to pro mě může být dobrá volba, a ptali jsme se na to zde .

20
elethan

Toto je řešení, s nímž jsem skončil, a naše aplikace fungují ve výrobě bez problémů po dobu téměř jednoho měsíce s touto opravou na místě:

Jediné, co jsem musel udělat, bylo přidat

--ignore-installed

do pip install řádků v mém dockfile, které vykazovaly chyby. Použitím stejného příkladu dockerfile z mé původní otázky by pevný dockerfile vypadal jako:

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

Dokumentace, kterou jsem mohl najít pro --ignore-installed, byla podle mého názoru nejasná (pip install --help jednoduše říká: „Ignorujte nainstalované balíčky (místo toho přeinstalovat).“) A zeptal jsem se na potenciální nebezpečí tohoto příznaku zde , ale zatím jsem se nedostal uspokojující odpověď. Pokud však dojde k nějakým negativním vedlejším účinkům, naše výrobní prostředí ještě nevidí jejich důsledky a myslím si, že riziko je nízké/žádné (alespoň to byla naše zkušenost). Byl jsem schopen potvrdit, že v našem případě, když byl tento příznak použit, nebyla stávající instalace odinstalována, ale že byla vždy použita novější instalace. 

Aktualizace:

Chtěl jsem zdůraznit toto odpověď od @ivan_pozdeev. Poskytuje některé informace, které tato odpověď nezahrnuje, a také nastiňuje některé potenciální vedlejší účinky mého řešení. 

42
elethan

Numpy můžete odebrat pouze ručně, ale ostatní závislosti instalované aptem. Pak použijte pip jako před instalací nejnovější verze 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

Umístění numpy by mělo být stejné. Pokud však chcete potvrdit umístění, můžete spustit kontejner bez spuštění souborů requirements.txt a vydat následující příkazy v konzole python uvnitř kontejneru.

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

Tohle pro mě fungovalo -

pip install --ignore-installed 

nebo Sudo pip install --ignore-installed 

nebo (uvnitř poznámkového bloku) import sys ! {sys.executable} -m pip install --ignore-installed 

0
Archie Jain