ホイールハウスで社内 Python インデックスを立てる
目標
接続された側で、Pythonパッケージと依存関係をwheelとして集めてハッシュで固定したあと、エアギャップ環境側にPEP 503の社内インデックスを立てて、pip.confで指し示し、外部がふさがれてもインストールできることを確認します。
なぜ重要なのか
エアギャップ環境への持ち込みで、最もコストの高いミスは、「取得して持っていったのに足りなくて、もう一度出てくること」と、「取得して持っていったのに、サーバーで合わないこと」です。前者は、依存関係を外部で丸ごと解決して持っていけば防げ、後者は、対象サーバーのPythonのバージョンとプラットフォームを指定して取得すれば防げます。そして、媒体を通る間に書き換えられたファイルは、ハッシュ検証モードが捕まえます。このPodは、最初からインターネット(80/443)に届くので、ダウンロード側の役割を果たし、エアギャップ環境側の確認は、採点が、外部へ向かうHTTP(S)を閉じたプロキシに向けてふさいだ状態で行います。
ステップ
requests==2.32.3とその依存関係を、このPodのPython(3.12)用のwheelだけで取得して、/root/pip/wheelhouse/に集めてください。- エアギャップ環境のサーバーは、Python 3.11(x86_64、manylinux2014)です。同じ要件を、その対象用のwheelで取得して、
/root/pip/wheelhouse-py311/に集めてください。 /root/pip/wheelhouse/のwheelのすべてを、이름==버전 --hash=sha256:<값>の行で書いた/root/pip/requirements.txtを作成してください(プレースホルダーは名前とバージョンとハッシュ値です)。/srv/pypi/simple/<정규화한 이름>/ディレクトリごとに(プレースホルダーは正規化した名前です)、該当するwheelを入れて、PEP 503の形のインデックスを作成してください。/etc/hostsに127.0.0.1 pypi.airgap.internalを追加して、/srv/pypiを8080ポートで公開するpython3 -m http.serverを起動してください。アクセス記録は、/root/pip/index.logに残します。/etc/pip.confに、index-url = http://pypi.airgap.internal:8080/simpleと、そのアドレスを信頼する設定を書いてください。採点は、外部をふさいだ状態で、この設定だけでrequestsが取得できるかを見ます。- venv
/root/pip/venvを作成して、requirements.txtをハッシュ検証モードでインストールしてください。 - インデックスがない場所を想定して、venv
/root/pip/venv-usbに、--no-index --find-links /root/pip/wheelhouseで、同じ要件をインストールしてください。
参考
- 取得だけ:
pip download -d <디렉터리> ...(プレースホルダーはディレクトリです)・対象の指定:--platform manylinux2014_x86_64 --python-version 3.11 --only-binary=:all: - ハッシュ1行:
pip hash <휠>(プレースホルダーはwheelです)・どの設定ファイルが読まれたか:pip config debug - 名前の正規化: 小文字に変えて、
.・-・_の連なりを-1つに。charset_normalizer→charset-normalizer - よくある間違い1:
http://の社内インデックスで、trusted-hostを外すこと。pipは警告だけを残して、インデックスを無視します。 - よくある間違い2: システムPythonに、直接インストールしてしまうこと。Ubuntu 24.04は、PEP 668でブロックします。venvを使ってください。
- よくある間違い3: サーバーを起動したターミナルを閉じたり、サーバーを停止したりしてしまうこと。ステップ6–7の採点は、サーバーが起動している必要があります。
ダウンロード側: 依存関係までwheelで取得する
requests==2.32.3とその依存関係を、このPodのPython用のwheelだけで取得して、/root/pip/wheelhouse/に集めてください。
pipには、インストールせずにファイルだけを集めるサブコマンドがあります。ソース配布物(.tar.gz)が混ざると、エアギャップ環境のサーバーでビルドツールを要求されるので、バイナリだけを取得させるオプションも、一緒に使ってください。
対象サーバーのPythonに合わせて取得する
Python 3.11(x86_64、manylinux2014)のサーバー用に、同じ要件を取得して、/root/pip/wheelhouse-py311/に集めてください。
pip downloadは、対象のプラットフォームとPythonのバージョンを、別に指定できます。ドキュメントが、それらのオプションと一緒に必ず使うよう書いているオプションが、1つあります。取得したあと、ファイル名のタグ(cp311など)を見てください。
バージョンとハッシュで固定する
/root/pip/wheelhouse/のwheelのすべてを、이름==버전 --hash=sha256:<값>の行で書いた/root/pip/requirements.txtを作成してください(プレースホルダーは名前とバージョンとハッシュ値です)。
wheelのファイル名の最初の2つの区切りが、名前とバージョンです。ハッシュは、pipが直接計算してくれるサブコマンドがあり、sha256sumと同じ値です。1行に、要件と--hashを一緒に書きます。
PEP 503の形の社内インデックスを作成する
/srv/pypi/simple/<정규화한 이름>/ディレクトリごとに(プレースホルダーは正規化した名前です)、該当するwheelを入れてください。
ディレクトリ名は、パッケージ名を仕様どおりに正規化したものでなければ、pipが見つけられません。小文字で、ドット・ハイフン・アンダースコアの連なりは、ハイフン1つです。wheelのファイル名の中のアンダースコアと、混同しないでください。
社内の名前でインデックスを起動する
/etc/hostsに127.0.0.1 pypi.airgap.internalを追加して、/srv/pypiを8080で公開するサーバーを起動してください。アクセス記録は、/root/pip/index.logに残します。
Pythonの標準ライブラリのhttp.serverは、ディレクトリの一覧を、ファイル名のリンクとして出します。公開するディレクトリとポートを引数として渡し、ターミナルを閉じても生き続けるように、バックグラウンドで起動してください。このサーバーは、アクセス記録を標準エラー出力に出します。
pip.confで社内インデックスを指し示す
/etc/pip.confに、index-url = http://pypi.airgap.internal:8080/simpleと、そのアドレスを信頼する設定を書いてください。
httpsではないインデックスは、pipがデフォルトでは信頼しません(localhostだけが例外)。ホスト名を信頼させる設定キーがあります。pip config debugで、ファイルが実際に読まれているかを確認してください。
ハッシュ検証モードでvenvにインストールする
venv /root/pip/venvを作成して、/root/pip/requirements.txtを、ハッシュ検証モードでインストールしてください。
Ubuntu 24.04のシステムPythonには、直接インストールできません。venvを作成してから、その中のpipで、requirementsファイルをインストールしてください。ファイルに--hashがあれば、ハッシュ検証モードが有効になりますが、明示するオプションもあります。
インデックスなしで、wheelhouseだけでインストールする
venv /root/pip/venv-usbを作成して、--no-index --find-links /root/pip/wheelhouseで、/root/pip/requirements.txtをインストールしてください。
インデックスをまったく見ないようにするオプションと、ファイルを探すディレクトリを指定するオプションを、一緒に使います。このインストールができれば、wheelhouseが自己完結しているという意味です。