pipをグローバルで使っていた環境でyumで入れたパッケージがおかしくなった話
※過去に自分が他の媒体で書いていた記事を移動してきたものなので、情報が古い可能性があります。ご注意ください。
yumとpipの競合
pipのインストール状況によりますが、yum経由でインストールしたPythonパッケージも、pipでグローバルにインストールしたパッケージも同じディレクトリにインストールされてしまうことがあります(例:/usr/lib/python2.7/site-packages/
)
このような状態でグローバルでpipを使用すると、yum経由でインストールしたPythonパッケージを上書きできてしまいます。
競合によって発生する問題
yumでインストールしたパッケージがエラーで利用できなくなることがあります。
また、yumからはpipがPythonパッケージを更新したことを検知できないため、yumによるパッケージの管理で一部の依存関係が自動で解決できなくなります。
実際に起きたpipによるPythonパッケージの上書きが原因となった問題
SSL証明書の更新で利用しているcertbotがある日、モジュールの不整合を起こすようになりました。
一見、pyOpenSSLのバージョン不整合が問題のようですが、実際はyumのrequests, urllib3, sixのPythonパッケージをpipで上書きしてしまったのが原因でした。
問題となっているパッケージをpipでアンインストールして、yumで再インストールしたところ、エラーが発生しなくなりました。
sudo pip uninstall requests sudo pip uninstall urllib3 sudo pip uninstall six sudo yum reinstall python-requests sudo yum install python-urllib3 sudo yum install python-six
競合を起こさないようにするには
システムにpipをインストールせず、仮想環境内でのみpipを扱うようにします。
少なくともCentOSは7でもシステムの使っているPythonが2.7.5なのでpipが付属していません(執筆当時の情報なので変わる可能性があります) そのため、python2-pipなどをインストールしなければ、誤ってシステムで使ってしまうことはありません。
yumでpython-virtualenvをインストールします。
sudo yum install python-virtualenv
仮想環境を作り、その中でpipを使うようにします。
virtualenv myenv source myvenv/bin/active
virtualenv内で使えるpipはおそらくバージョンが古いため、開発等をおこなう前にアップデートをおこないます。pipが使用するsetuptoolsのパッケージもアップデートします。
pip install -U pip pip install -U setuptools
すでに競合が起きている場合
競合の見つけ方
rpm -qV {パッケージ名}
でパッケージのファイルの検証ができます。
元のパッケージから変更されている箇所があれば、そのファイルの変更状態が出力されます。変更が無ければ何も出力されません。
$ rpm -qV httpd S.5....T. c /etc/httpd/conf.d/autoindex.conf S.5....T. c /etc/httpd/conf/httpd.conf /run/httpd/htcacheclean が見つかりません。 (許可がありません) ..?...... /usr/sbin/suexec /var/cache/httpd/proxy が見つかりません。 (許可がありません)
yumで管理しているpythonのパッケージ名が大体わかっているのであれば、検証用のシェルを書いて一気に処理を回してしまっても良いかもしれません。
#!/bin/sh for package in `rpm -qa | egrep "python|pytz|yum"` do echo $package rpm -qV $package done
あるいはpipでパッケージをインストールした時のログが残っているのであれば、内容からpipが上書きした可能性のあるパッケージにあたりをつけることができます。
# ログ中にこの記述がある場合、yumのパッケージをpipで上書きしている可能性があります Found existing installation: urllib3 1.10.2 Uninstalling urllib3-1.10.2: Successfully uninstalled urllib3-1.10.2
競合の直し方
pipでアンインストールして、使っているパッケージ管理ソフトで再インストールします。
pipはyumのように履歴からロールバックができないので、現在のパッケージのインストール状況を復元できるようにバックアップを取っておきます。
pip freeze > packages_requirements.txt
pipでパッケージをアンインストールします。 依存パッケージは自動でアンインストールされないので、必要があれば依存するパッケージも手動でアンインストールします。
sudo pip uninstall urllib3
yumでパッケージを再インストールします。 yum reinstallでエラーが起こる場合はコマンドをyum installに変更してください。
sudo yum reinstall python-urllib3
pipのアンインストール
yumからpipをインストールした場合は、yumでアンインストールします。 pipに依存するパッケージも一緒に削除されるので、依存関係をよく確認してからremoveを実行してください。
sudo yum remove pip
get-pip.pyを実行してpipをインストールした場合は、pipコマンドでpipをアンインストールします。 インストール時にpipとwheelがまとめてインストールされているはずなので、wheelも一緒にアンインストールします。
sudo pip uninstall wheel sudo pip uninstall pip
Pythonのバージョンによっては、標準でpipが付属していますが、その場合はアンインストールはしないようにしてください。
参考ページ
Tadej Janež – Don't mix yum/dnf and pip for installation of system-wide Python packages