¿Cómo replicar la selección de paquetes instalados de una instancia de Fedora a otra?

16

Tengo un sistema Fedora (A) donde he instalado algunos paquetes a lo largo del tiempo. Ahora quiero instalar Fedora en otra computadora (B) y quiero instalar los mismos paquetes en ella.

En términos de Debian, quiero lograr algo como esto:

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

Pero para ser honesto, realmente quiero un mejor método para seleccionar los mismos paquetes en el nuevo sistema Fedora 19 (B): solo quiero instalar los paquetes del sistema A que se mencionaron explícitamente en una dnf install(o yum install) línea de comando, y no los que fueron instalados como dependencias!

¿Por qué? Porque tal vez las dependencias han cambiado, y no quiero instalar dependencias desactualizadas en el nuevo sistema. Además, cuando elimino paquetes, también quiero eliminar las (posiblemente) dependencias instaladas automáticamente innecesarias (es decir, huérfanos).

He encontrado dnf list installed, pero no se muestra si un paquete se seleccionó explícitamente o simplemente se instaló debido a una dependencia.

¿Cómo obtengo esa información en Fedora?

¿Cuál es la forma Fedora / dnf de replicar las selecciones de paquetes?

maxschlepzig
fuente

Respuestas:

12

Desde Fedora 26, el Dnf repoquery subcomando admite una nueva opción para enumerar todos los paquetes instalados por el usuario:

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

A diferencia de otros métodos, también enumera todos los paquetes de debuginfo. El grep adicional en el ejemplo anterior los filtra.

Para instalar la lista en el host B:

$ < pkgs_a.lst xargs dnf -y install

API de Dnf

Con las versiones recientes de Dnf (por ejemplo, Fedora> = 23), la base de datos de paquetes puede consultarse por los nombres de paquetes instalados por el usuario a través de la API de 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

Por defecto, dnf installaborta si uno o más paquetes ya no están disponibles. Alternativamente, dnf puede verse obligado a instalar todos los restantes:

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

PD: Ponga el código anterior y más enuser-installed.py eso también es compatible con otras distribuciones.

historial instalado por el usuario

En Fedora 23 y posterior, Dnf proporciona el

# dnf history userinstalled

comando que enumera todos los paquetes instalados por el usuario. A partir de 2016-11, su utilidad es limitada porque no hay forma de controlar su salida e imprime paquetes totalmente calificados (es decir, que incluye información de versión).

Limitaciones instaladas por el usuario

Tenga en cuenta que el marcado de paquetes como instalados por el usuario tiene algunas limitaciones en algunas versiones de Fedora, para los sistemas Fedora 23-ish era (de alrededor de 2015-11) los siguientes problemas son relevantes):

Repoquery

En sistemas Fedora más antiguos, donde Dnf, la API de Dnf y dnf history userinstalledno están disponibles, uno puede usar repoquery , por ejemplo:

$ 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

La segunda condición awk se usa para excluir paquetes que fueron instalados por el instalador. La identificación de usuario del instalador aparentemente se almacenó como 4294967295; alternativamente, puede escribir algo como ($3 == 0 || $3 == your-user-id).

Tenga en cuenta que este comando funciona en Fedora hasta la versión 21, pero, por ejemplo, no en la versión 23, porque el comando repoqueryfue reemplazado por dnf repoquery. Y dnf repoqueryno entiende la %{yumdb_info.reason}etiqueta.

maxschlepzig
fuente
No estoy seguro de si este enfoque obtendrá todo, noté esto en mi sistema cuando ejecuté repoquery ...: "Motivo de consulta inválido yumdb 'razón' para el paquete instalado: HandBrake-cli-0.9.5-1.fc14.x86_64"
slm
@slm, hm, ¿desde qué repositorio se instaló el freno de mano? ¿Quizás la configuración del repositorio tiene algo que ver con eso?
maxschlepzig
Creo que podría haber sido un RPM independiente que instalé usando yum localinstall .... Sin embargo, tuve una buena cantidad de paquetes que cayeron en ese campamento.
slm
repoquery --installed --qf '%{n} - %{yumdb_info.reason}' --all 2>&1|grep -v "user$"|grep -v "dep$" |wc -ldevolvió 90 paquetes.
slm
6

La forma más fácil y ha funcionado durante mucho tiempo es:

yum-debug-dump => gives file.

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

... que funciona de manera muy similar al comando get / set selections dpkg, AIUI. También tenga en cuenta que si está reproduciendo el historial puede usar:

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

... en lugar de tener que analizarlo usted mismo.

James Antill
fuente
3

Inspirado por la respuesta de slm , se me ocurrió la siguiente solución basada:yum history

Obtenga todo el historial detallado de todas las transacciones de instalación de yum (es decir, sin actualizaciones), excluidas las ejecutadas como parte de las acciones iniciales del instalador (transacciones 1 y 2 en mi sistema, atribuidas al usuario 'Sistema'):

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

Filtra los paquetes instalados explícitamente y corta los prefijos de versión.

$ < 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

La expresión regular fea es necesaria para que coincidan todos los tipos de sufijos de versión.

Los resultados se ven bastante bien en mi sistema.

Una comparación contra el repositorio ansatz (en mi sistema):

método # paquetes
"" "" "" "" ""
Repoquery 569
repoquery-2nd 216
ñam historia 214

(Canalicé los resultados del repositorio a través de sort -u)

¿Por qué hay diferencias? Porque el repositorio incluye todos los paquetes de las transacciones 1 y 2, es decir, todos los paquetes que fueron instalados por el instalador de Fedora. Esto explica por qué el repositorio incluye los paquetes mencionados xorg-x11- drv-mga y amigos.

La comparación de repoquery-2nd y yum-history muestra que repoquery-2nd es más preciso: no incluye algunos paquetes ya eliminados. Además, parece que incluye algunos paquetes (2 en mi sistema) de operaciones 'yum update'.

Advertencia

El método basado en el historial anterior solo enumera todos los paquetes instalados explícitamente durante la vida útil completa del sistema. No equilibra los paquetes que se eliminaron en una transacción posterior. Por lo tanto, este método necesita un tratamiento manual de los resultados y solo debe usarse en sistemas donde repoqueryno está disponible.

maxschlepzig
fuente
¡Buena manera de aprovechar al máximo nuestras dos respuestas! Le daría más de un +1 si pudiera para la solución final + la buena comparación de las diversas formas de hacerlo.
slm
2

Tengo una versión anterior de Fedora (14), por lo que mi yum incluye una versión menos rica en funciones yum, pero es posible que desee echar un vistazo a la yum historyfunción. Creo que puede obtener la información que busca de ese comando.

lista de historia

$ 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   
   ...

Puede volver a la primera transacción pasando una lista de números a 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

información de la historia

Lo siguiente le mostrará lo que se instaló como parte de la primera transacción anual:

$ 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

Observe cómo yum informa si un paquete se instaló o instaló explícitamente porque lo necesitaba una dependencia. Puede analizar esta información y obtener su lista de paquetes que se instalaron explícitamente.

slm
fuente
He agregado una respuesta basada en su yum historyidea, también compara los resultados con el repoquerymétodo basado. Como efecto secundario, he extendido mi respuesta de respuesta.
maxschlepzig
1
dnf repoquery --qf "%{name}" --userinstalled > userinstalled.txt
Flo
fuente
1
Al mirar las otras 5 respuestas aquí, ¿qué nota que es diferente en su respuesta? No hay absolutamente ninguna explicación de por qué o cómo su respuesta es mejor o diferente. Sería bueno si pudiera proporcionar una descripción de su respuesta que cubra estas cosas.
Stephen Rauch
@StephenRauch, este comando no está incluido en las otras respuestas, porque es una adición reciente de dnf. El --userinstalledcambio se agregó a dnf en mayo . Lo he probado y da resultados precisos. Module los paquetes kernel / kernel-core / kernel-modules que no están realmente instalados por el usuario. También contiene todos los *-debuginfopaquetes, pero se pueden filtrar fácilmente, si es necesario.
maxschlepzig
@maxschlepzig, gracias por los comentarios, pero en realidad fue una pregunta retórica, tratando de educar / incitar al respondedor a explicar eso en la respuesta.
Stephen Rauch
@StephenRauch, bastante justo, alguna edición ciertamente sería apropiada y me permitiría marcarla como respuesta aceptada.
maxschlepzig
0

Para enumerar los paquetes que ha instalado, intente con esta línea :

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

Resultado:

# 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: no muestra dependencias

PS2: se ordena alfabéticamente

PS3: no se muestra si ha eliminado el paquete más tarde

Fernando Fabreti
fuente
-1

Lo que hice (olvidé los detalles, y soy un vago flojo, así que ...

Obtenga todos los paquetes instalados: rpm -qa > file

Úselo sed(1)para deshacerse de los números de versión y demás (mantenga la arquitectura, si es necesario). Esto requirió algunas iteraciones para hacerlo bien, desea reemplazar el último tramo de -[0-9.]-[0-9].fc23o similar por nada, pero también hay "números" de versión divertida.

Después de instalar normalmente, haga un yum -y install $(< file)(o dnf, según sea necesario).

Obtendrá algunas consecuencias de los paquetes que ya no existen o que cambiaron de nombre o fueron reemplazados por otros.

vonbrand
fuente
Ok, pero esto marcará todos los paquetes instalados previamente como instalados por el usuario en el host de destino. Incluso si originalmente solo se instalaron como una dependencia.
maxschlepzig