Как скопировать выбранный пакет из одного экземпляра Fedora в другой?

16

У меня есть система Fedora (A), где я со временем установил несколько пакетов. Теперь я хочу установить Fedora на другой компьютер (B) и установить на него те же пакеты.

В терминах Debian я хочу сделать что-то вроде этого:

$ dpkg --get-selections > pkg_sel_host_a  # on host_a
$ dpkg --set-selections < pkg_sel_host_a  # on host_b

Но, честно говоря, я действительно хочу лучший способ выбрать те же пакеты в новой системе Fedora 19 (B): я просто хочу установить пакеты из системы A, которые были явно упомянуты в dnf install(или yum install) командной строке - а не те, которые были установлены как зависимости!

Почему? Потому что, возможно, зависимости изменились - и я не хочу устанавливать устаревшие зависимости в новой системе. Плюс, когда я удаляю пакеты, я хочу удалить (возможно), а затем ненужные автоматически установленные зависимости (т.е. сироты).

Я нашел dnf list installed- но он не отображается, если пакет был явно выбран или просто установлен из-за зависимости.

Как я могу получить эту информацию о Fedora?

Как Fedora / dnf способ реплицировать выбранные пакеты?

maxschlepzig
источник

Ответы:

12

Начиная с Fedora 26, repoquery подкоманда Dnf поддерживает новую опцию для перечисления всех установленных пользователем пакетов:

$ dnf repoquery --qf '%{name}' --userinstalled \
 | grep -v -- '-debuginfo$' \
 | grep -v '^\(kernel-modules\|kernel\|kernel-core\|kernel-devel\)$' > pkgs_a.lst

В отличие от других методов, в нем также перечислены все пакеты debuginfo. Дополнительный grep в приведенном выше примере отфильтровывает их.

Чтобы установить список на хосте B:

$ < pkgs_a.lst xargs dnf -y install

Dnf API

В последних версиях Dnf (например, Fedora> = 23) база данных пакетов может запрашиваться для имен установленных пользователем пакетов через API-интерфейс Dnf Python:

$ python3 -c 'import dnf; b = dnf.Base(); b.fill_sack(); \
  l = sorted(set(x.name for x in b.iter_userinstalled() \
       if not x.name.endswith("-debuginfo") \
          and x.name not in \
             ["kernel-modules", "kernel", "kernel-core", "kernel-devel"] )); \
  print("\n".join(l)) ' > pkgs_a.lst

# dnf install $(cat pkgs_a.lst) # on host_b

По умолчанию dnf installпрерывается, если один или несколько пакетов больше не доступны. В качестве альтернативы, dnf можно принудительно установить все остальные:

# dnf install --setopt=strict=0 $(cat pkgs_a.lst) # on host_b

PS: поместите приведенный выше код и многое другое, user-installed.pyчто также поддерживает другие дистрибутивы.

История пользователя установлена

На Fedora 23 и позже Dnf предоставляет

# dnf history userinstalled

команда, которая выводит список всех установленных пользователем пакетов. По состоянию на 2016-11 гг. Его полезность ограничена, потому что нет способа контролировать его вывод, и он печатает пакеты с полной квалификацией (т.е. включая информацию о версии).

Ограничения, установленные пользователем

Обратите внимание, что пометка пакетов как установленных пользователем имеет некоторые ограничения для некоторых версий Fedora, для систем Fedora 23-го периода (примерно с 2015 по 2011 год) актуальны следующие проблемы):

Repoquery

В более старых системах Fedora, где Dnf, Dnf API и dnf history userinstalledнедоступны, можно вместо этого использовать repoquery , например:

$ repoquery --installed \
     --qf '%{n} | %{yumdb_info.reason} | %{yumdb_info.installed_by}' --all \
    | awk -F'|' ' $2 ~ /user/ && ($3 != 4294967295) { print $1 }'  \
    | sort -u > pkgs_a.lst

Второе условие awk используется для исключения пакетов, которые были установлены установщиком. Идентификатор пользователя установщика, очевидно, был сохранен как 4294967295 - в качестве альтернативы вы можете написать что-то вроде ($3 == 0 || $3 == your-user-id).

Обратите внимание, что эта команда работает в Fedora вплоть до выпуска 21 - но, например, не в выпуске 23, потому что команда repoqueryбыла заменена на dnf repoquery. И dnf repoqueryне понимает %{yumdb_info.reason}тег.

maxschlepzig
источник
Я не уверен, что этот подход получит все, я заметил это в своей системе, когда запустил repoquery ...: «Недопустимый тег запроса yumdb 'причина' для установленного pkg: HandBrake-cli-0.9.5-1.fc14.x86_64"
slm
@slm, хм, из какого репозитория был установлен ручной тормоз? Возможно, настройка репозитория как-то связана с этим?
maxschlepzig
Я думаю, что это мог быть автономный RPM, который я установил, используя yum localinstall .... У меня было достаточно пакетов, которые упали в этот лагерь, хотя.
SLM
repoquery --installed --qf '%{n} - %{yumdb_info.reason}' --all 2>&1|grep -v "user$"|grep -v "dep$" |wc -lвернул 90 посылок.
SLM
6

Самый простой способ, и он работал долго:

yum-debug-dump => gives file.

yum-debug-restore <file-from-debug-dump>

... которая работает так же, как команда get / set selections dpkg, AIUI. Также обратите внимание, что если вы воспроизводите историю, вы можете использовать:

yum history addon-info last saved_tx => gives file
yum load-tx <file-from-addon-info>

... вместо того, чтобы разбирать его самостоятельно.

Джеймс Антилл
источник
3

Вдохновленный ответом slm , я нашел следующее решение:yum history

Получить всю подробную историю по всем транзакциям установки yum (т.е. без обновлений), за исключением тех, которые выполнялись как часть начальных действий установщика (транзакции 1 и 2 в моей системе, приписанные пользователю 'System'):

$ yum history list all | awk -F'|' \
                            '$4 ~ /Install/ && $2 !~ /System/ {print $1}' \
    | xargs yum history info > yum_history

Фильтруйте явно установленные пакеты и обрезайте префиксы версий.

$ < yum_history grep '[^-]\<Install\>' | \
  awk '{ print $2 }' \
  | sed 's/\(-[0-9]\+:\|-[0-9]\+\.[0-9]\|-[0-9]\+-\|-[0-9]\+git\).\+\(\.fc1[1-7]\.\|\.noarch\).*$//' \
  | sort > hist_pkg_list

Гадкое регулярное выражение необходимо, чтобы все виды суффиксов версий были сопоставлены.

Результаты выглядят довольно хорошо в моей системе.

Сравнение с анзацем репо-запросов (в моей системе):

метод # пакеты
-------------------------
repoquery 569
репок-2-й 216
ням история 214

(Я передал результаты репо через sort -u)

Почему есть различия? Поскольку repoquery включает в себя все пакеты из транзакций 1 и 2, то есть все пакеты, которые были установлены установщиком Fedora. Это объясняет, почему repoquery включает в себя упомянутые пакеты xorg-x11-drv-mga и друзей.

Сравнение repoquery-2nd и yum-history показывает, что repoquery-2nd более точен - он не включает некоторые уже удаленные пакеты. Кроме того, он включает в себя несколько (2 в моей системе) пакетов из операций 'yum update'.

Предупреждение

Вышеупомянутый основанный на истории метод только перечисляет все явно установленные пакеты в течение полного срока службы системы. Это не уравновешивает те пакеты, которые были удалены в более поздней транзакции. Таким образом, этот метод требует некоторой ручной обработки результатов и должен использоваться только в тех системах, в которых repoqueryон недоступен.

maxschlepzig
источник
Хороший способ взять лучшее из обоих наших ответов! Я бы дал вам больше, чем +1, если бы я мог за возможное решение + хорошее сравнение различных способов сделать это.
slm
2

У меня есть более старая версия Fedora (14), поэтому моя ням включает менее функциональную версию yum, но вы можете взглянуть на эту yum historyфункцию. Я верю, что вы можете получить информацию, которую вы ищете из этой команды.

список истории

$ sudo yum history list
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
ID     | Login user             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
   862 | System <unset>         | 2013-07-12 18:00 | Install        |    1   
   861 | System <unset>         | 2013-07-09 03:11 | Install        |    1   
   860 | System <unset>         | 2013-07-01 13:40 | Install        |    1   
   859 | System <unset>         | 2013-06-29 22:07 | Install        |    1   
   858 | System <unset>         | 2013-06-25 22:33 | Install        |    1 P<
   857 | System <unset>         | 2013-06-23 22:28 | Update         |    1 >E
   856 | System <unset>         | 2013-06-23 21:33 | Install        |    1   
   ...

Вы можете вернуться к самой первой транзакции, передав список номеров yum history list:

$ sudo yum history list `seq 1 10`
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
ID     | Login user             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
    10 | Sam M. (local) <saml>  | 2010-12-18 23:23 | Install        |    2   
     9 | Sam M. (local) <saml>  | 2010-12-18 23:15 | Install        |   38   
     8 | Sam M. (local) <saml>  | 2010-12-18 23:12 | Install        |    1   
     7 | Sam M. (local) <saml>  | 2010-12-18 23:09 | Install        |    1  <
     6 | Sam M. (local) <saml>  | 2010-12-18 22:37 | Install        |    1 > 
     5 | Sam M. (local) <saml>  | 2010-12-18 21:57 | Install        |    1   
     4 | System <unset>         | 2010-12-18 21:21 | Install        |    5   
     3 | System <unset>         | 2010-12-18 21:18 | Install        |    4   
     2 | System <unset>         | 2010-12-18 21:10 | Install        |    3   
     1 | System <unset>         | 2010-12-18 19:14 | Install        | 1189

информация об истории

Следующее покажет вам, что было установлено как часть транзакции 1st yum:

$ sudo yum history info 1 | less
Loaded plugins: langpacks, presto, refresh-packagekit
Adding en_US to language list
Transaction ID : 1
Begin time     : Sat Dec 18 19:14:05 2010
Begin rpmdb    : 0:da39a3ee5e6b4b0d3255bfef95601890afd80709
End time       :            19:42:43 2010 (1718 seconds)
End rpmdb      : 1189:8c21e9e377c3ebdee936916208f74232d5d6235f
User           : System <unset>
Return-Code    : Success
Transaction performed with:
Packages Altered:
    Dep-Install ConsoleKit-0.4.2-3.fc14.x86_64
    Dep-Install ConsoleKit-libs-0.4.2-3.fc14.x86_64
    Dep-Install ConsoleKit-x11-0.4.2-3.fc14.x86_64
    Dep-Install GConf2-2.31.91-1.fc14.x86_64
    Dep-Install GConf2-gtk-2.31.91-1.fc14.x86_64
    Dep-Install ModemManager-0.4-4.git20100720.fc14.x86_64
    Install     NetworkManager-1:0.8.1-10.git20100831.fc14.x86_64
    Dep-Install NetworkManager-glib-1:0.8.1-10.git20100831.fc14.x86_64
    Install     NetworkManager-gnome-1:0.8.1-10.git20100831.fc14.x86_64
    Install     NetworkManager-openconnect-0.8.1-1.fc14.x86_64

Обратите внимание, как yum сообщает, был ли пакет явно установлен или установлен, потому что он был необходим для зависимости. Вы можете проанализировать эту информацию и получить список пакетов, которые были явно установлены.

SLM
источник
Я добавил ответ, основанный на вашей yum historyидее, он также сравнивает результаты с repoqueryоснованным методом. В качестве побочного эффекта я расширил свой ответ на повторный запрос.
maxschlepzig
1
dnf repoquery --qf "%{name}" --userinstalled > userinstalled.txt
Фло
источник
1
Когда вы просматриваете остальные 5 ответов здесь, что вы замечаете, что отличается от вашего ответа? Там нет абсолютно никакого объяснения того, почему или как ваш ответ лучше отличается. Было бы хорошо, если бы вы могли дать некоторое описание вашего ответа, который охватывает эти вещи.
Стивен Раух
@StephenRauch, эта команда не включена в другие ответы, потому что это недавнее добавление dnf. --userinstalledПереключатель был просто добавлен в DNF в мае . Я проверил это, и это дает точные результаты. По модулю пакеты kernel / kernel-core / kernel-modules, которые на самом деле не установлены пользователем. Он также содержит все *-debuginfoпакеты, но при необходимости их можно легко отфильтровать.
maxschlepzig
@maxschlepzig, спасибо за отзыв, но на самом деле это был немного риторический вопрос, пытаясь научить / побудить ответчика объяснить это в ответе.
Стивен Раух
@ StephhenRauch, честно говоря, определенное редактирование, безусловно, будет уместным и позволит мне пометить его как принятый ответ.
maxschlepzig
0

К списку пакетов вы установили, попробуйте этот один вкладыш :

alias yum-userinstall="yumdb search command_line install* | grep command_line\ = | sort | uniq | sed -r -e 's/command_line = (.*)/yum \1/g'"

Результат:

# yum-userinstall
     yum install bind-utils
     yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
     yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
     yum install lsof
     yum install nano
     yum install nfs-utils libnfsidmap
     yum install nmap-ncat
     yum install openscap-scanner
     yum install open-vm-tools

PS1: это не показывает зависимости

PS2: отсортировано по алфавиту

PS3: он не показывает, если вы удалили пакет позже

Фернандо Фабрети
источник
-1

Что я сделал (забыл подробности, а я ленивая задница, так что ...

Получить все установленные пакеты: rpm -qa > file

Используйте, sed(1)чтобы избавиться от номеров версий и тому подобного (сохранить архитектуру, если требуется). Для этого потребовалось несколько итераций, вы хотите заменить последний отрезок -[0-9.]-[0-9].fc23или подобный ничем, но есть и забавные версии «чисел».

После установки, как обычно, сделайте yum -y install $(< file)(или dnf, как требуется).

Вы получите некоторые пакеты, которые больше не существуют, или изменили имя, или были заменены другими.

vonbrand
источник
Хорошо, но это пометит все ранее установленные пакеты как установленные пользователем на целевом хосте. Даже если они изначально были установлены только как зависимость.
maxschlepzig