종속성을 존중하면서 여러 deb 파일 설치


13

여러 파일 의 오프라인 설치 를 지원하기 위해 .deb다음을 사용하고 있습니다.

sudo dpkg -i dependencies/*.deb

설치 순서에 따라이 방법을 사용하여 일부 패키지가 실패하는 것으로 나타났습니다.

예를 들어, 이것은 내가 설치할 때 발생하는 mariadb-server-5.5일과 그 종속성입니다.

이것들은 파일입니다

이것은 오류입니다

*.deb종속성을 존중하면서 파일을 어떻게 설치 합니까?

  • 유지 관리가 어렵 기 때문에 로컬 리포지토리 설정을 피하려고합니다.
  • 해결 방법으로 명령을 dpkg -i *.deb두 번 실행 합니다.

1
GDebi 를 사용해 보셨습니까 ? dpkg의존성 관리와 관련하여 평범한 것보다 더 똑똑 합니다. --apt-line플래그를 사용하여 결과 조치를 시뮬레이션 할 수 있습니다 .
David Foerster

이것은 오래된 질문이지만 어떻게했는지에 대해 커뮤니티로 돌아갈 수 있기를 바랍니다. 1) 설치를 두 번 실행하면 (두 번째 단계는 정상입니까?) 또는 2) apt-get install -f
pzkpfw

1
@pzkpfw는 현재 두 번 설치를 실행 중입니다. 의존성을 토폴로지 순서로 정렬하기 위해 Python 스크립트 작성 계획. 배포하자마자 업데이트됩니다
Jossef Harush

그것이 끊어지지 않으면 그것을 고치지 않는 것 같아요 :)
pzkpfw

답변:


3

-R을 사용하여 시도하고 옵션을 설치할 수 있습니다.

sudo dpkg -R --install dependencies/

-R 재귀는 특정 디렉토리 및 모든 서브 디렉토리에있는 패턴 * .deb와 일치하는 모든 일반 파일을 처리합니다.


-1, 작동하지 않습니다. 같은 상황
Jossef Harush

2

토폴로지 정렬 (스크립트를 통해)

이 명령 은 문제 가 있습니다. 모든 필수 패키지를 제공하더라도 패키지를 설치해야하는 순서를 제대로 준수하지 않습니다.dpkg -i packages/*.deb

그들 모두를 지배하는 커스텀 스크립트

데비안 배포판 에 파이썬이 설치되어 있다고 가정합니다 (광산은 우분투 14.04 LTS이며 함께 제공됩니다 python27)

오프라인 .deb packages디렉토리와 별도로 스크립트를 제공하십시오.

  • 메타 데이터 추출 및 토폴로지를 통해 모든 후보 패키지 정렬
  • 용도는 dpkg -i그들이 설치해야 올바른 순서로 정렬 된 패키지를 설치합니다

예를 들어, 사전 수집 된 모든 오프라인 패키지를 설치하려면이 명령을 실행하십시오.

sudo python install.py
  • 디렉토리 구조는 다음과 같아야합니다

    여기에 이미지 설명을 입력하십시오


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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.