Instale múltiples archivos deb respetando sus dependencias

12

Para admitir la instalación sin conexión de varios .debarchivos, estoy usando:

sudo dpkg -i dependencies/*.deb

He notado que algunos paquetes fallan al usar este método debido al orden en que se instalaron

Por ejemplo, esto es lo que sucede cuando instalo mariadb-server-5.5y sus dependencias:

estos son los archivos

este es el error

¿Cómo puedo instalar *.debarchivos respetando sus dependencias?

  • Estoy tratando de evitar establecer un repositorio local, ya que es más difícil de mantener.
  • Como solución alternativa, ejecuto el comando dpkg -i *.debdos veces.
Jossef Harush
fuente
1
¿Has probado GDebi ? Es un poco más inteligente que simple dpkgcon respecto a la gestión de dependencias. Puede simular las acciones resultantes con la --apt-linebandera.
David Foerster
Esta es una vieja pregunta, pero espero que puedas volver a la comunidad sobre cómo hiciste esto. Me interesaría si lo intentó 1) Simplemente ejecutando la instalación dos veces (¿el segundo paso debería estar bien?) O 2) Cualquier otra alternativa, como apt-get install -f
pzkpfw
1
@pzkpfw actualmente solo ejecuta la instalación dos veces. Planeando escribir un script de Python para ordenar las dependencias en orden topológico. Se actualizará tan pronto como lo implemente
Jossef Harush
Si no está roto, no lo arregles, supongo :)
pzkpfw

Respuestas:

3

Puede probar con -R e instalar opciones:

sudo dpkg -R --install dependencies/

-R Recursive maneja todos los archivos regulares que coinciden con el patrón * .deb encontrado en directorios específicos y todos sus subdirectorios

mauek unak
fuente
-1, esto no funciona. misma situación en cuestión
Jossef Harush
2

Clasificación topológica (a través de script)

El comando es problemático : no respeta correctamente el orden en que deben instalarse los paquetes (incluso si proporciona todos los paquetes necesarios).dpkg -i packages/*.deb

Script personalizado para gobernarlos a todos

Bajo el supuesto de que su distribución de Debian tiene Python instalado (el mío es Ubuntu 14.04 LTS y viene con python27)

Aparte del packagesdirectorio .deb fuera de línea , proporcione un script que;

  • Extrae metadatos y ordena topológicamente todos los paquetes candidatos
  • Usos dpkg -ipara instalar los paquetes ordenados en el orden correcto en que deberían instalarse

Por ejemplo, ejecute este comando para instalar todos los paquetes fuera de línea recopilados previamente

sudo python install.py
  • La estructura de tu directorio debería verse así

    ingrese la descripción de la imagen aquí


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
fuente