Come replicare la selezione dei pacchetti installati da un'istanza Fedora a un'altra?


16

Ho un sistema Fedora (A) in cui ho installato alcuni pacchetti nel tempo. Ora voglio installare Fedora su un altro computer (B) e voglio installare gli stessi pacchetti su di esso.

In termini Debian voglio realizzare qualcosa del genere:

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

Ma ad essere sincero, voglio davvero un metodo migliore per selezionare gli stessi pacchetti sul nuovo sistema Fedora 19 (B): voglio solo installare i pacchetti dal sistema A che sono stati esplicitamente menzionati su una dnf install(o yum install) riga di comando - e non quelli che sono stati installati come dipendenze!

Perché? Perché forse le dipendenze sono cambiate e non voglio installare dipendenze obsolete sul nuovo sistema. Inoltre, quando rimuovo i pacchetti desidero rimuovere anche le dipendenze (eventualmente) non installate automaticamente installate (ovvero gli orfani).

Ho trovato dnf list installed, ma non viene visualizzato se un pacchetto è stato selezionato in modo esplicito o è stato appena installato a causa di una dipendenza.

Come posso ottenere queste informazioni su Fedora?

Qual è il modo Fedora / dnf per replicare le selezioni dei pacchetti?

Risposte:


12

A partire da Fedora 26, il repoquery sottocomando Dnf supporta una nuova opzione per elencare tutti i pacchetti installati dall'utente:

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

A differenza di altri metodi, elenca anche tutti i pacchetti debuginfo. Il grep aggiuntivo nell'esempio sopra li filtra.

Per installare l'elenco sull'host B:

$ < pkgs_a.lst xargs dnf -y install

API Dnf

Con le versioni recenti di Dnf (ad es. Fedora> = 23), è possibile eseguire una query sul database dei pacchetti per i nomi dei pacchetti installati dall'utente tramite l'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

Per impostazione predefinita, dnf installinterrompe se uno o più pacchetti non sono più disponibili. In alternativa, dnf può essere costretto a installare tutti quelli rimanenti:

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

PS: inserisci il codice sopra e altro in user-installed.pyquello che supporta anche altre distribuzioni.

cronologia installata dall'utente

Su Fedora 23 e successive, Dnf fornisce il

# dnf history userinstalled

comando che elenca tutti i pacchetti installati dall'utente. A partire dall'11 / 2016/2016, la sua utilità è limitata perché non c'è modo di controllarne l'output e stampa pacchetti completamente qualificati (cioè includendo informazioni sulla versione).

Limitazioni installate dall'utente

Nota che la marcatura dei pacchetti come installati dall'utente ha alcune limitazioni su alcune versioni di Fedora, per i sistemi Fedora dell'era 23 (circa 2015-11) sono rilevanti i seguenti problemi:

repoquery

Sui vecchi sistemi Fedora, dove Dnf, l'API Dnf e dnf history userinstallednon sono disponibili, è possibile utilizzare invece il repoquery , ad esempio:

$ 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 seconda condizione awk viene utilizzata per escludere i pacchetti installati dal programma di installazione. L'ID utente dell'installatore era apparentemente memorizzato come 4294967295 - in alternativa puoi scrivere qualcosa del genere ($3 == 0 || $3 == your-user-id).

Nota che questo comando funziona su Fedora fino alla versione 21, ma ad esempio non sulla versione 23, perché il comando è repoquerystato sostituito con dnf repoquery. E dnf repoquerynon capisce il %{yumdb_info.reason}tag.


Non sono sicuro che questo approccio ottenga tutto, ho notato queste cose sul mio sistema quando ho eseguito repoquery ...: "Querytag yumdb 'reason' non valido per pkg installato: HandBrake-cli-0.9.5-1.fc14.x86_64"
slm

@slm, hm, da quale repository è stato installato il freno a mano? Forse l'installazione del repository ha qualcosa a che fare con esso?
maxschlepzig,

Penso che potrebbe essere stato un RPM autonomo che ho installato usando yum localinstall .... Avevo una discreta quantità di pacchi che però caddero in quel campo.
slm

repoquery --installed --qf '%{n} - %{yumdb_info.reason}' --all 2>&1|grep -v "user$"|grep -v "dep$" |wc -lrestituito 90 pacchi.
slm

6

Il modo più semplice ed ha funzionato a lungo è:

yum-debug-dump => gives file.

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

... che funziona in modo molto simile al comando dpkg get / set selections, AIUI. Inoltre, se stai riproducendo la cronologia, puoi utilizzare:

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

... invece di doverlo analizzare da solo.


3

Ispirato dalla risposta di slm , ho trovato la seguente soluzione di base:yum history

Ottieni tutta la cronologia dettagliata di tutte le transazioni di installazione di yum (ovvero senza aggiornamenti), escluse quelle eseguite come parte delle azioni iniziali dell'installer (transazioni 1 e 2 sul mio sistema, attribuite all'utente "Sistema"):

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

Filtra i pacchetti installati in modo esplicito e taglia i prefissi di versione.

$ < 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 brutta espressione regolare è necessaria in modo tale che tutti i tipi di suffissi versione siano abbinati.

I risultati sembrano abbastanza buoni sul mio sistema.

Un confronto con il repoquery ansatz (sul mio sistema):

metodo # pacchetti
-------------------------
repoquery 569
repoquery-2nd 216
storia di yum 214

(Ho convogliato i risultati del repoquery tramite sort -u)

Perché ci sono differenze? Perché repoquery include tutti i pacchetti delle transazioni 1 e 2, cioè tutti i pacchetti che sono stati installati dal programma di installazione di Fedora. Questo spiega perché repoquery include i pacchetti citati xorg-x11-drv-mga e amici.

Il confronto tra repoquery-2nd e yum-history mostra che repoquery-2nd è più preciso, non include alcuni pacchetti già rimossi. Inoltre include alcuni (2 sul mio sistema) pacchetti dalle operazioni 'yum update', a quanto pare.

avvertimento

Il precedente metodo basato sulla cronologia elenca solo tutti i pacchetti installati in modo esplicito per l'intera durata del sistema. Non equilibra quei pacchetti che sono stati rimossi in una transazione successiva. Pertanto, questo metodo richiede una cura manuale dei risultati e dovrebbe essere utilizzato solo su sistemi repoquerynon disponibili.


Bel modo di ottenere il meglio da entrambe le nostre risposte! Ti darei più di un +1 se potessi per l'eventuale soluzione + il bel confronto dei vari modi di farlo.
slm

2

Ho una versione precedente di Fedora (14), quindi il mio yum include una versione meno ricca di funzionalità yum, ma potresti voler dare un'occhiata alla yum historyfunzione. Credo che tu possa ottenere le informazioni che stai cercando da quel comando.

elenco cronologico

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

Puoi tornare alla prima transazione passando un elenco di numeri 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

informazioni sulla storia

Quanto segue ti mostrerà cosa è stato installato come parte della prima transazione 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

Notare come yum segnala se un pacchetto è stato installato o installato esplicitamente perché era necessario a una dipendenza. È possibile analizzare queste informazioni e ottenere l'elenco dei pacchetti che sono stati installati in modo esplicito.


Ho aggiunto una risposta in base alla tua yum historyidea, confronta anche i risultati con il repoquerymetodo basato. Come effetto collaterale ho esteso la mia risposta al repoquery.
maxschlepzig,

1
dnf repoquery --qf "%{name}" --userinstalled > userinstalled.txt

1
Mentre guardi le altre 5 risposte qui, cosa noti che è diverso nella tua risposta? Non c'è assolutamente alcuna spiegazione del perché o di come la tua risposta sia migliore delle diverse. Sarebbe bello se potessi fornire una descrizione della tua risposta che copre queste cose.
Stephen Rauch,

@StephenRauch, questo comando non è incluso nelle altre risposte, perché è una recente aggiunta dnf. Lo --userinstalledswitch è stato appena aggiunto a dnf a maggio . L'ho provato e dà risultati accurati. Modulo i pacchetti kernel / kernel-core / kernel-modules che non sono realmente installati dall'utente. Contiene inoltre tutti i *-debuginfopacchetti, ma possono essere facilmente filtrati, se necessario.
Maxschlepzig,

@maxschlepzig, grazie per il feedback, ma in realtà era una domanda retorica, cercare di educare / spingere il rispondente a spiegarlo nella risposta.
Stephen Rauch,

@StephenRauch, abbastanza giusto, alcune modifiche sarebbero certamente appropriate e mi permetterebbero di contrassegnarlo come risposta accettata.
Maxschlepzig,

0

Per elencare i pacchetti che hai installato, prova questo one-liner :

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

Risultato:

# 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: non mostra dipendenze

PS2: è in ordine alfabetico

PS3: non mostra se hai rimosso il pacchetto in seguito


-1

Quello che ho fatto (ho dimenticato i dettagli e sono un pigrone, quindi ...

Ottieni tutti i pacchetti installati: rpm -qa > file

Utilizzare sed(1)per sbarazzarsi dei numeri di versione e simili (mantenere l'architettura, se necessario). Ciò ha richiesto alcune iterazioni per farlo bene, vuoi sostituire l'ultimo tratto -[0-9.]-[0-9].fc23o simile con niente, ma ci sono anche "numeri" divertenti della versione.

Dopo l'installazione come di consueto, eseguire un yum -y install $(< file)(o dnf, come richiesto).

Riceverai alcune ricadute di pacchetti che non esistono più, o cambiano nome o sono stati sostituiti da altri.


Ok, ma questo contrassegnerà tutti i pacchetti precedentemente installati come installati dall'utente sull'host di destinazione. Anche se originariamente erano installati solo come dipendenza.
maxschlepzig,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.