Zainstaluj wiele plików deb, uwzględniając ich zależności

13

Do obsługi instalacji wielu .debplików offline używam:

sudo dpkg -i dependencies/*.deb

Zauważyłem, że niektóre pakiety nie działają przy użyciu tej metody z powodu kolejności, w jakiej zostały zainstalowane

Na przykład tak się dzieje, gdy instaluję mariadb-server-5.5i jego zależności:

to są pliki

to jest błąd

Jak mogę instalować *.debpliki z poszanowaniem ich zależności?

  • Staram się unikać tworzenia lokalnego repozytorium, ponieważ trudniej go utrzymać.
  • Aby obejść ten problem, uruchamiam polecenie dpkg -i *.debdwukrotnie.
Jossef Harush
źródło
1
Czy próbowałeś GDebi ? Jest to odrobinę bardziej inteligentne niż proste w dpkgzakresie zarządzania zależnościami. Możesz symulować wynikowe działania za pomocą --apt-lineflagi.
David Foerster,
To stare pytanie, ale mam nadzieję, że wrócisz do społeczności, jak to zrobiłeś? Byłbym zainteresowany, czy próbowałeś 1) Wystarczy uruchomić instalację dwukrotnie (drugie przejście powinno być OK?) Lub 2) Każda inna alternatywa, na przykład apt-get install -f
pzkpfw
1
@ pzkpfw obecnie właśnie uruchamia instalację dwukrotnie. Planowanie napisania skryptu pythonowego do sortowania zależności w kolejności topologicznej. Zaktualizuje się, gdy tylko go
wdrożę
Jeśli to nie jest zepsute, nie naprawiaj tego chyba
pzkpfw

Odpowiedzi:

3

Możesz spróbować z opcją -R i zainstalować opcje:

sudo dpkg -R --install dependencies/

-R Rekurencyjne obsługuje wszystkie zwykłe pliki pasujące do wzorca * .deb znalezionego w określonych katalogach i wszystkich jego podkatalogach

mauek unak
źródło
-1, to nie działa. taka sama sytuacja jak w pytaniu
Jossef Harush
2

Sortowanie topologiczne (za pomocą skryptu)

Polecenie jest problematyczne - nie przestrzega poprawnie pakietów zamówień, które należy zainstalować (nawet jeśli dostarczysz wszystkie wymagane pakiety).dpkg -i packages/*.deb

Skrypt niestandardowy, aby rządzić nimi wszystkimi

Przy założeniu, że twoja dystrybucja Debiana ma zainstalowanego Pythona (mój jest Ubuntu 14.04 LTS i pochodzi z python27)

Oprócz packageskatalogu .deb offline , podaj skrypt, który;

  • Wyodrębnij metadane i Topologiczne sortuje wszystkie pakiety kandydujące
  • Używa dpkg -ido instalowania posortowanych pakietów w odpowiedniej kolejności, w jakiej powinny zostać zainstalowane

Na przykład wykonaj to polecenie, aby zainstalować wszystkie wstępnie zebrane pakiety offline

sudo python install.py
  • Struktura katalogu powinna wyglądać następująco

    wprowadź opis zdjęcia tutaj


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
źródło