4 votes

Générer un graphe de dépendances pour l'ensemble du système

Je connais debtree pour générer un graphe de dépendances pour un paquet donné comme celui-ci :

sudo apt-get install debtree
sudo apt-get install graphviz
debtree alsa-base > alsa-base.dot
dot -T png -o alsa-base.png alsa-base.dot

Mais que faire si je veux un graphique de dépendances pour l'ensemble du système, avec chaque paquet affiché une seule fois ?

1voto

JulianWgs Points 126

Voici un moyen détourné de le faire en Python.

Commencez par écrire tous les paquets installés dans un fichier.

apt list --installed > installed_packages.txt

Itérer sur cette liste et obtenir les dépendances de premier ordre de chaque paquet avec debtree. Cela peut prendre un certain temps, si vous avez beaucoup de paquets (surtout des lib*).

Ce script est mieux exécuté dans un environnement interactif comme Jupyter Lab. Il met en cache tout le travail dans edges_dict et saute le processus de récupération s'il a déjà une entrée.

import json
import subprocess
from io import StringIO
import pydot
import networkx as nx

names = [package.split("/")[0] for package in open("installed_packages.txt").read().split("\n")[1:-1]]

edges_dict = dict()

command = "debtree --with-suggests --max-depth 1 {}"
for name in names:
    if name not in edges_dict.keys():
        try:
            process = subprocess.Popen(command.format(name).split(), stdout=subprocess.PIPE)
            output, error = process.communicate()
            if error is None:
                g = nx.drawing.nx_pydot.read_dot(StringIO(output.decode()))
                edges_dict[name] = list(g.edges())
            else:
                print(name, error)
        except:
            print(name, "Failed")

json.dump(edges_dict, open("edges.json", "w"))
edges_dict = json.load(open("edges.json"))

Avec ces données, vous pouvez soit créer un graphique avec networkx...

import networkx as nx
g = nx.DiGraph()
for name, edges in edges_dict.items():
    g.add_edges_from(edges)

ou un DataFrame avec pandas.

data = list()
for name, edges in edges_dict.items():
    for node1, node2 in edges:
        data.append([name, node1, node2])

df = pd.DataFrame(data, columns=["name", "package", "dependency"])

# many packages have themself as a dependency
df = df[df["package"] != df["dependency"]]

J'espère que cela vous aidera :)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X