Instal beberapa file deb sambil menghormati dependensinya

12

Untuk mendukung instalasi beberapa .debfile offline , saya menggunakan:

sudo dpkg -i dependencies/*.deb

Saya perhatikan beberapa paket gagal menggunakan metode ini karena urutan yang mereka instal

Sebagai contoh, inilah yang terjadi ketika saya menginstal mariadb-server-5.5dan dependensinya:

ini adalah file

ini kesalahannya

Bagaimana saya dapat menginstal *.debfile sambil menghormati ketergantungannya?

  • Saya mencoba untuk menghindari membuat repo lokal, karena sulit untuk mempertahankannya.
  • Sebagai solusinya, saya menjalankan perintah dpkg -i *.debdua kali.
Jossef Harush
sumber
1
Sudahkah Anda mencoba GDebi ? Ini sedikit lebih cerdas daripada polos dpkgtentang manajemen ketergantungan. Anda dapat mensimulasikan tindakan yang dihasilkan dengan --apt-linebendera.
David Foerster
Ini adalah pertanyaan lama tetapi mudah-mudahan Anda dapat kembali ke komunitas tentang bagaimana Anda melakukan ini? Saya akan tertarik pada apakah Anda mencoba 1) Hanya menjalankan instalasi dua kali (pass kedua harus OK?) Atau 2) Alternatif lain, seperti apt-get install -f
pzkpfw
1
@pzkpfw saat ini hanya menjalankan instalasi dua kali. Berencana untuk menulis skrip python untuk mengurutkan dependensi dalam urutan topologis. Akan diperbarui segera setelah saya akan menerapkannya
Jossef Harush
Jika tidak rusak jangan memperbaikinya kurasa :)
pzkpfw

Jawaban:

3

Anda dapat mencoba dengan -R dan menginstal opsi:

sudo dpkg -R --install dependencies/

-R Recursive menangani semua file biasa dengan pola yang cocok * .deb ditemukan di direktori tertentu dan semua subdirektori

mauek unak
sumber
-1, ini tidak berhasil. situasi yang sama seperti dalam pertanyaan
Jossef Harush
2

Urutan topologis (melalui skrip)

Perintahnya bermasalah - tidak menghormati dengan benar paket pesanan harus diinstal (bahkan jika Anda menyediakan semua paket yang diperlukan).dpkg -i packages/*.deb

Skrip khusus untuk mengatur semuanya

Dengan asumsi distro debian Anda telah diinstal python (milik saya adalah ubuntu 14.04 LTS dan disertai python27)

Selain packagesdirektori .deb offline , berikan skrip yang;

  • Ekstrak metadata dan Topologi mengurutkan semua paket kandidat
  • Penggunaan dpkg -iuntuk menginstal paket yang diurutkan dalam urutan yang tepat mereka harus diinstal

Misalnya, jalankan perintah ini untuk menginstal semua paket offline yang dikumpulkan sebelumnya

sudo python install.py
  • Struktur direktori Anda akan terlihat seperti ini

    masukkan deskripsi gambar di sini


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
sumber