Installieren Sie mehrere deb-Dateien unter Berücksichtigung ihrer Abhängigkeiten

12

Um die Offline-Installation mehrerer .debDateien zu unterstützen, verwende ich:

sudo dpkg -i dependencies/*.deb

Ich habe festgestellt, dass einige Pakete mit dieser Methode aufgrund der Reihenfolge, in der sie installiert wurden, fehlschlagen

Das passiert zum Beispiel, wenn ich installiere mariadb-server-5.5und die Abhängigkeiten:

das sind die dateien

das ist der fehler

Wie kann ich *.debDateien unter Berücksichtigung ihrer Abhängigkeiten installieren ?

  • Ich versuche zu vermeiden, ein lokales Repo einzurichten, da es schwieriger ist, es zu pflegen.
  • Um dies zu umgehen, führe ich den Befehl dpkg -i *.debzweimal aus.
Jossef Harush
quelle
1
Hast du GDebi ausprobiert ? In dpkgBezug auf das Abhängigkeitsmanagement ist es ein bisschen intelligenter als normal . Sie können die daraus resultierenden Aktionen mit dem --apt-lineFlag simulieren .
David Foerster
Dies ist eine alte Frage, aber hoffentlich können Sie zur Community zurückkehren, wie Sie dies getan haben? Es würde mich interessieren, ob Sie versucht haben, 1) die Installation nur zweimal
auszuführen
1
@pzkpfw führt die Installation derzeit nur zweimal aus. Planen Sie, ein Python-Skript zu schreiben, um die Abhängigkeiten in topologischer Reihenfolge zu sortieren. Wird aktualisiert, sobald ich es bereitstelle
Jossef Harush
Wenn es nicht kaputt ist, repariere es nicht, denke ich :)
pzkpfw

Antworten:

3

Sie können es mit -R versuchen und Optionen installieren:

sudo dpkg -R --install dependencies/

-R Rekursiv behandelt alle regulären Dateien, die mit dem Muster * .deb in bestimmten Verzeichnissen und allen Unterverzeichnissen übereinstimmen

mauek unak
quelle
-1, das funktioniert nicht. gleiche Situation wie in Frage
Jossef Harush
2

Topologische Sortierung (über Skript)

Der Befehl ist problematisch - hält sich nicht an die Reihenfolge, in der die Pakete installiert werden sollen (auch wenn Sie alle erforderlichen Pakete angeben).dpkg -i packages/*.deb

Benutzerdefiniertes Skript, um sie alle zu regieren

Unter der Annahme, dass Ihre Debian-Distribution Python installiert hat (meine ist Ubuntu 14.04 LTS und kommt mit python27)

Geben Sie neben dem Offline- packagesVerzeichnis .deb ein Skript an, das:

  • Metadaten extrahieren und Topologisch sortiert alle Kandidatenpakete
  • Verwendet dpkg -i, um die sortierten Pakete in der richtigen Reihenfolge zu installieren, in der sie installiert werden sollen

Führen Sie beispielsweise diesen Befehl aus, um alle vorab gesammelten Offline-Pakete zu installieren

sudo python install.py
  • Ihre Verzeichnisstruktur sollte so aussehen

    Bildbeschreibung hier eingeben


install.py

#!/usr/bin/env python

import os
import re
import subprocess
import logging

import sys

rootLogger = logging.getLogger()
rootLogger.setLevel(logging.INFO)
consoleHandler = logging.StreamHandler(sys.stdout)
consoleHandler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
rootLogger.addHandler(consoleHandler)

SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))


class TopologicalSort(object):
    def __init__(self, dependency_map):
        self._dependency_map = dependency_map
        self._already_processed = set()

    def _get_dependencies(self, item, root=None):

        if not root:
            root = item

        elif root == item:
            logging.warn("circular dependency detected in '{}'".format(item))
            raise StopIteration()

        dependencies = self._dependency_map.get(item, [])
        for dependency in dependencies:

            if dependency in self._already_processed:
                continue

            self._already_processed.add(dependency)

            for sub_dependency in self._get_dependencies(dependency, root=root):
                yield sub_dependency

            yield dependency

    def sort(self):
        # Reduction, connect all nodes to a dummy node and re-calculate
        special_package_id = 'topological-sort-special-node'
        self._dependency_map[special_package_id] = self._dependency_map.keys()
        sorted_dependencies = self._get_dependencies(special_package_id)
        sorted_dependencies = list(sorted_dependencies)
        del self._dependency_map[special_package_id]

        # Remove "noise" dependencies (only referenced, not declared)
        sorted_dependencies = filter(lambda x: x in self._dependency_map, sorted_dependencies)
        return sorted_dependencies


class DebianPackage(object):
    def __init__(self, file_path):
        metadata = subprocess.check_output('dpkg -I {}'.format(file_path), shell=True)
        metadata = metadata.replace('\n ', '\n')
        self._metadata = metadata
        self.id = self._get('Package')
        self.dependencies = list(self._get_dependencies())
        self.file_path = file_path

    def _get_dependencies(self):
        dependencies = self._get('Depends') + ',' + self._get('Pre-Depends')
        dependencies = re.split(r',|\|', dependencies)
        dependencies = map(lambda x: re.sub(r'\(.*\)|:any', '', x).strip(), dependencies)
        dependencies = filter(lambda x: x, dependencies)
        dependencies = set(dependencies)
        for dependency in dependencies:
            yield dependency

    def _get(self, key):
        search = re.search(r'\n{key}:(.*)\n[A-Z]'.format(key=key), self._metadata)
        return search.group(1).strip() if search else ''


def sort_debian_packages(directory_path):
    file_names = os.listdir(directory_path)
    debian_packages = {}
    dependency_map = {}
    for file_name in file_names:

        file_path = os.path.join(directory_path, file_name)

        if not os.path.isfile(file_path):
            continue

        debian_package = DebianPackage(file_path)
        debian_packages[debian_package.id] = debian_package
        dependency_map[debian_package.id] = debian_package.dependencies

    sorted_dependencies = TopologicalSort(dependency_map).sort()
    sorted_dependencies = map(lambda package_id: debian_packages[package_id].file_path, sorted_dependencies)
    return sorted_dependencies


def main():
    # ------------------
    # Sort the packages using topological sort

    packages_dir_path = os.path.join(SCRIPT_DIR, 'packages')
    logging.info('sorting packages in "{}" using topological sort ...'.format(packages_dir_path))
    sorted_packages = sort_debian_packages(packages_dir_path)

    # ------------------
    # Install the packages in the sorted order

    for index, package_file_path in enumerate(sorted_packages):
        command = 'dpkg -i {}'.format(package_file_path)
        logging.info('executing "{}" ...'.format(command))
        subprocess.check_call(command, shell=True)


if __name__ == '__main__':

    if os.geteuid() != 0:
        logging.error('must be run as root')
        sys.exit(1)

    try:
        main()
    except:
        logging.error('failed to install packages', exc_info=True)
        sys.exit(1)
Jossef Harush
quelle