yumでインストールするパッケージの依存関係を再帰的に知りたかった
はじめに
yum deplist [パッケージ]でそのパッケージのインストールする際の依存関係がわかるが、
「じゃあ依存関係にあるパッケージの依存関係はどうなん?」というのを見てみたくなった。
ので作った。
利用用途?知らない。
何か「yumで勝手にインストールするな!依存関係を全て調べろ!」とかいう人に出してあげれば良いんじゃん?
知らんけど。再帰関数あまり使わないな練習しよと思ってなんとなーくネタが出来たので作ったまで
ロジック関連
yum deplist [パッケージ]の結果は以下のようになる。
package: httpd.x86_64 2.4.52-1.amzn2 dependency: /bin/sh provider: bash.x86_64 4.2.46-34.amzn2 dependency: /etc/mime.types provider: mailcap.noarch 2.1.41-2.amzn2 dependency: config(httpd) = 2.4.52-1.amzn2 provider: httpd.x86_64 2.4.52-1.amzn2 dependency: httpd-filesystem provider: httpd-filesystem.noarch 2.4.52-1.amzn2 dependency: libc.so.6()(64bit) provider: glibc.x86_64 2.26-57.amzn2 dependency: libc.so.6(GLIBC_2.14)(64bit) provider: glibc.x86_64 2.26-57.amzn2 dependency: libc.so.6(GLIBC_2.2.5)(64bit) provider: glibc.x86_64 2.26-57.amzn2
このprovider:以下が依存関係が入っているパッケージなので、このyum deplistの結果を受け取り、正規表現でprovider:の後ろをリストで取得。
各パッケージに大して再度yum deplistすれば良い。
ただし以下のような注意点がある。
①↑の通り同じproviderが複数出るパターンが有る。
→重複は削除する(別に出してもいいけどノイズになるので)
②依存パッケージの依存関係を調べたら、上位で依存関係として出てきたパッケージが出るパターンがある。(無限ループする)
→すでに上位で依存すると分かっているなら下位では調べない。
例えば以下みたいな感じ
yum deplist glibc.x86_64 2.26-57.amzn2 →結果にprovider: glibc-minimal-langpack.x86_64 2.26-57.amzn2 →yum deplist glibc-minimal-langpack.x86_64 2.26-57.amzn2 →結果にprovider: glibc.x86_64 2.26-57.amzn2(↑と同じ) →yum deplist glibc.x86_64 2.26-57.amzn2 →以下無限ループ
これを考慮して出力が以下になるようにインデント数を調整する
解析したいパッケージ 依存パッケージA 依存パッケージA-1 依存パッケージB 依存パッケージB-1 依存パッケージB-2
出来上がったのがこちら
# coding: UTF-8 import subprocess import traceback import re import sys from collections import OrderedDict #上位パッケージですでに依存関係があると分かっている物を保存しておくメモ(下位パッケージで上位と同じパッケージが出てくるパターンが有った。無限ループになるのでメモ化) memo = [] def analyzeDependency(indentCount,package): """ 依存関係を解析する """ printDependencyPackage(indentCount,package) #依存関係取得 dependPackages = getDependencyPackages(package) if len(dependPackages) > 0: for dependPackage in dependPackages: if dependPackage not in memo: #メモに追加 memo.append(dependPackage) analyzeDependency(indentCount+1,dependPackage) else: if isPrintFull: printDependencyPackage(indentCount+1,dependPackage+"(already depend)") def getDependencyPackages(package): """ 指定されたパッケージの依存関係を取得 """ cmd = "yum deplist " + package res = execCmd(cmd) #依存関係のあるパッケージのリストを取得 dependPackages = re.findall("provider: (.*)",res.decode("utf-8")) #重複削除 return list(OrderedDict.fromkeys(dependPackages)) def printDependencyPackage(indentCount,package): """ 出力 """ indentStr = "" for i in range(indentCount): indentStr += " " print(indentStr+package) def execCmd(cmd): """ コマンド実行 """ try: res = subprocess.check_output(cmd,shell=True,stderr=subprocess.DEVNULL) return res except Exception as e: print("Exec Error cmd:%s" % cmd) raise e isPrintFull = False def main(): """ yumでインストールする際の依存関係を解析するツール 解析したいパッケージ 依存パッケージA 依存パッケージA-1 依存パッケージB 依存パッケージB-1 依存パッケージB-2 ... というような出力を行う。(インデントはスペース) yum deplist [パッケージ名]が使える環境であること 第二引数にfullをつけると、上位ですでに依存すると分かっているパッケージも下位で表示する """ try: argv = sys.argv package = argv[1] if len(argv) >= 3 and "full" == argv[2]: global isPrintFull isPrintFull = True print("*print full*") else: print("*print summary*") #依存関係解析 analyzeDependency(0,package) except Exception as e: print(e) if __name__ == '__main__': main()
※githubにも上げた。
GitHub - y-osaru/dependency_analyzer: yum依存関係解析ツール
実行するとこんな感じになる(クソ長いので一部抜粋)
*print summary* httpd bash.x86_64 4.2.46-34.amzn2 glibc.x86_64 2.26-57.amzn2 basesystem.noarch 10.0-7.amzn2.0.1 filesystem.x86_64 3.2-25.amzn2.0.4 setup.noarch 2.8.71-10.amzn2.0.1 system-release.x86_64 1:2-14.amzn2 glibc.i686 2.26-57.amzn2 glibc-common.x86_64 2.26-57.amzn2 libselinux.x86_64 2.5-12.amzn2.0.2 pcre.x86_64 8.32-17.amzn2.0.2 libgcc.x86_64 7.3.1-13.amzn2 libstdc++.x86_64 7.3.1-13.amzn2 libsepol.x86_64 2.5-8.1.amzn2.0.2 pcre.i686 8.32-17.amzn2.0.2 libgcc.i686 7.3.1-13.amzn2 libstdc++.i686 7.3.1-13.amzn2 tzdata.noarch 2021e-1.amzn2 glibc-minimal-langpack.x86_64 2.26-57.amzn2 ncurses-libs.x86_64 6.0-8.20170212.amzn2.1.3 ncurses-base.noarch 6.0-8.20170212.amzn2.1.3 mailcap.noarch 2.1.41-2.amzn2 httpd.x86_64 2.4.52-1.amzn2 httpd-filesystem.noarch 2.4.52-1.amzn2 shadow-utils.x86_64 2:4.1.5.1-24.amzn2.0.2 audit-libs.x86_64 2.8.1-3.amzn2.1 audit-libs.i686 2.8.1-3.amzn2.1 libcap-ng.i686 0.7.5-4.amzn2.0.4 libcap-ng.x86_64 0.7.5-4.amzn2.0.4 coreutils.x86_64 8.22-24.amzn2 info.x86_64 5.1-5.amzn2 zlib.x86_64 1.2.7-18.amzn2 gmp.x86_64 1:6.0.0-15.amzn2.0.2 gmp.i686 1:6.0.0-15.amzn2.0.2
依存関係を調べるコマンドと正規表現を換えれば他のディストリビューションでも使えるかもね。
終わり。