はじめに
BenchTicket はイベントの注文を窓口で使える料金表に変換します。現在のインストールは二つの供給元を検索し、正常に完了しても同名の代替パッケージによって料金が変わります。
正常な業務出力を比較し、インストールされた依存を調べ、承認済みツールを再構築する手順を保存します。パッケージ名と供給元はすべて合成したもので、このラボ内に限定されます。基本的なターミナルとテキストファイルの操作が前提です。Python のプログラミングは不要です。
チケット窓口の正常な例を読む
依存を変更する前に料金表を理解します。Terminal から始めます。cd はディレクトリを移動します。絶対パスは現在地に関係なく使えます。
cd /home/labex/project/ticket-build
orders.csv は小さなカンマ区切り表です。各注文には ID、大人と子どもの人数、会員の値があります。cat で表示します。
cat orders.csv
大人は 1200 セント、子どもは 600 セントです。大人と子どもがそれぞれ二人以上なら 400 セント引き、会員ならさらに 200 セント引きで、最低額はゼロです。1 セントは通貨単位の百分の一です。
用意された demo は独立した承認済みサンプル環境を実行します。自分のプロジェクト環境を完成させるものではありません。
/opt/labex-lookalike/demo
T101 は 3200,32.00、T103 は 1600,16.00、T104 はゼロのままです。この関係はパッケージのバージョン表示より重要です。元の注文とアプリは変更しません。
インストール成功でも料金が誤ることを観察する
インストールの成功と業務結果の正しさを区別します。Terminal の ticket-build に留まります。
仮想環境はプロジェクト専用の Python パッケージを保存します。python3 はインタープリター、-m はモジュール実行です。venv モジュールが環境を作ります。用意された pip が --python で別環境を管理できるため、--without-pip は二つ目の pip コピーを省きます。
python3 -m venv --without-pip .venv
用意された手順を読みます。
cat install.sh
bash がこのスクリプトを実行します。"$1" は第一引数の環境パスです。引用符でパスを一つに保ちます。set -e はインストール失敗時に停止します。--isolated はユーザーの pip 設定と環境変数を無視し、--no-cache-dir はキャッシュ済みダウンロードを使いません。--index-url と --extra-index-url は二つの索引を指定し、-r は要件を読みます。
bash install.sh .venv
その環境のインタープリターで元の呼び出しプログラムを実行します。
.venv/bin/python quote.py orders.csv
T101 は誤って 3600,36.00、T103 は 1800,18.00 になります。この制御された代替品は計算だけを変更し、データは盗みません。インストールの正常終了だけでは正しい料金を証明できません。
リゾルバーが選んだものを特定する
誤動作を実際のインストール済みパッケージと結び付けます。パッケージ索引は利用可能な配布物を列挙し、wheel はインストール可能な Python パッケージのアーカイブです。
python3 -m pip は pip をモジュールとして実行します。show は --python で選んだ環境のインストール済みメタデータを読みます。
python3 -m pip --isolated --python .venv show benchticket-prices benchticket-labels
prices は benchticket-labels に依存する 9.0.0、labels は 1.0.0 のはずです。Labels は間接依存で、prices のインストールによって一緒に入りました。ここでは配布名のハイフンがインポート名のアンダースコアに対応します。
独立して提供された承認カタログを読みます。
cat /opt/labex-lookalike/approval/packages.tsv
承認済みは prices 1.4.0、labels 1.0.0 です。SHA-256 列は次のラボで使います。
Pip は両方の索引を検索します。--extra-index-url は低優先度の予備ではありません。ここでは条件を満たす高いバージョンが選ばれます。ローカルの public は合成された第二供給元で、本物の PyPI ではありません。次に、審査済みパッケージ群だけを使う手順にします。
承認済みの手順を保存して適用する
承認済みバージョンを保存し、承認済み索引を使います。== は厳密なバージョン指定です。
次の here-document はファイル全体を書きます。> は指定ファイルを置換し、<<'EOF' は EOF だけの行までを文字どおりに読み取ります。編集を許された二つの手順ファイルだけに使ってください。
cat > requirements.txt <<'EOF'
benchticket-prices==1.4.0
benchticket-labels==1.0.0
EOF
環境引数と失敗時の停止を保って手順を置き換えます。承認済み索引には両方のパッケージがあります。
cat > install.sh <<'EOF'
#!/bin/bash
set -e
python3 -m pip --isolated --python "$1" install --no-cache-dir --index-url http://127.0.0.1:8123/approved/simple -r requirements.txt
EOF
bash install.sh .venv
Pip は prices 9.0.0 を 1.4.0 に置換します。バージョンを再確認します。
python3 -m pip --isolated --python .venv show benchticket-prices benchticket-labels
両方ともカタログと一致するはずです。パスを誤入力したら cd /home/labex/project/ticket-build で戻り、cat で二つのファイルを調べて再インストールします。VM のリセットは不要です。
すべての注文を正しい料金で引き渡す
本物の窓口料金表を作ります。用意された呼び出しプログラムは CSV を読み、インストール済みパッケージの関数を呼び、金額を整形します。--output で結果を保存します。
.venv/bin/python quote.py orders.csv --output handover.csv
cat handover.csv
T101〜T105 の合計は順に 3200、1200、1600、0、4200 セントです。ID、数量、会員の値は正しい注文との対応を維持します。
diff -u は二つのテキストファイルを比較して変更行を表示します。独立して提供された例と比べます。
diff -u /opt/labex-lookalike/approval/reference.csv handover.csv
出力なしなら一致です。$? は直前のコマンドの終了状態を保持します。他のコマンドで変わる前に読みます。
echo $?
期待値は 0 です。相違があると 1 で、ファイル不在や Python のインポートエラーとは異なります。手順を修正して再インストールし、プログラムを再実行します。注文の編集や料金表の手入力はしないでください。
最初の環境を借りずに再構築する
保存した手順が現在のインストールから独立して動くことを確認します。第二の仮想環境には最初、チケット用パッケージがありません。
python3 -m venv --without-pip .rebuild
同じ手順へ別の対象を渡します。
bash install.sh .rebuild
.rebuild/bin/python quote.py orders.csv
同じ五つの正しい注文が出るはずです。元の .venv、保存した handover.csv、注文、プログラムはそのまま残ります。
これは提供された承認済み供給元で手順が動くことを示します。厳密なバージョンだけでは正確なバイトを固定できません。別の供給元は同名同版で異なる wheel を提供できます。次の独立ラボではハッシュでこの境界を作ります。
本ラボのサーバーは合成された制御下のもので、本番のプライベート索引ではありません。すべての供給元を閉じたり既知の CSV をコピーしたりすると、今示した有用な再構築ができなくなります。
まとめ
実際の料金を比較し、直接・間接依存を特定し、保存した手順から承認済みパッケージ群を再構築しました。元のデータやアプリを変えずに完全な料金表も引き渡しました。パッケージ選択とインストール成功は、業務結果の正しさとは別に確認するものです。



