Jak zreplikować wybór zainstalowanego pakietu z jednej instancji Fedory do drugiej?

16

Mam system Fedora (A), w którym z czasem zainstalowałem kilka pakietów. Teraz chcę zainstalować Fedorę na innym komputerze (B) i chcę zainstalować na nim te same pakiety.

W kategoriach Debiana chcę osiągnąć coś takiego:

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

Ale szczerze mówiąc, naprawdę chcę lepszej metody wybierania tych samych pakietów w nowym systemie Fedora 19 (B): Chcę tylko zainstalować pakiety z systemu A, które zostały wyraźnie wymienione w wierszu poleceń dnf install(lub yum install) - a nie te, które zostały zainstalowane jako zależności!

Dlaczego? Ponieważ być może zależności się zmieniły - i nie chcę instalować przestarzałych zależności w nowym systemie. Dodatkowo, kiedy usuwam pakiety, chcę również usunąć (ewentualnie) niepotrzebne automatycznie zainstalowane zależności (tj. Sieroty).

Znalazłem dnf list installed- ale nie wyświetla się, jeśli pakiet został wyraźnie wybrany lub po prostu zainstalowany z powodu zależności.

Jak uzyskać te informacje o Fedorze?

W jaki sposób Fedora / dnf może replikować wybrane pakiety?

maxschlepzig
źródło

Odpowiedzi:

12

Od wydania Fedory 26 podkomenda Dnf repoquery obsługuje nową opcję wyświetlania wszystkich pakietów zainstalowanych przez użytkownika:

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

W przeciwieństwie do innych metod wyświetla również wszystkie pakiety debuginfo. Dodatkowy grep w powyższym przykładzie je odfiltrowuje.

Aby zainstalować listę na hoście B:

$ < pkgs_a.lst xargs dnf -y install

Dnf API

W najnowszych wersjach Dnf (np. Fedora> = 23) do bazy danych pakietów można zapytać o nazwy pakietów instalowanych przez użytkownika za pomocą interfejsu 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

Domyślnie dnf installprzerywa, jeśli jeden lub więcej pakietów nie jest już dostępnych. Alternatywnie, dnf może zostać zmuszony do zainstalowania wszystkich pozostałych:

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

PS: Umieść powyższy kod i inne elementy, user-installed.pyktóre obsługują również inne dystrybucje.

historia zainstalowana przez użytkownika

W Fedorze 23 i nowszych Dnf zapewnia

# dnf history userinstalled

polecenie, które wyświetla listę wszystkich pakietów zainstalowanych przez użytkownika. Począwszy od 2016-11 roku, jego użyteczność jest ograniczona, ponieważ nie ma możliwości kontrolowania jego wyników i drukuje pakiety w pełni kwalifikowane (tj. Zawierające informacje o wersji).

Ograniczenia zainstalowane przez użytkownika

Zauważ, że oznaczanie pakietów jako instalowanych przez użytkownika ma pewne ograniczenia w niektórych wersjach Fedory, w przypadku systemów z 23-go okresu (od około 2015-11) istotne są następujące problemy):

Repoquery

W starszych systemach Fedory, w których Dnf, API Dnf i dnf history userinstallednie są dostępne, zamiast tego można użyć repozytorium , np .:

$ 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

Drugi warunek awk służy do wykluczenia pakietów, które zostały zainstalowane przez instalatora. Identyfikator użytkownika instalatora był najwyraźniej zapisany jako 4294967295 - alternatywnie możesz napisać coś takiego ($3 == 0 || $3 == your-user-id).

Zauważ, że to polecenie działa w Fedorze do wersji 21 - ale np. Nie w wersji 23, ponieważ to polecenie repoqueryzostało zastąpione dnf repoquery. I dnf repoquerynie rozumie %{yumdb_info.reason}tagu.

maxschlepzig
źródło
Nie jestem pewien, czy to podejście da wszystko, zauważyłem to w moim systemie, gdy uruchomiłem repoquery ...: „Nieprawidłowy„ powód ”yumdb querytag dla zainstalowanego pkg: HandBrake-cli-0.9.5-1.fc14.x86_64”
slm
@slm, hm, z jakiego repozytorium zainstalowano hamulec ręczny? Być może konfiguracja repozytorium ma z tym coś wspólnego?
maxschlepzig
Myślę, że mógł to być samodzielny RPM, którego zainstalowałem yum localinstall .... Miałem jednak sporo paczek, które trafiły do ​​tego obozu.
slm
repoquery --installed --qf '%{n} - %{yumdb_info.reason}' --all 2>&1|grep -v "user$"|grep -v "dep$" |wc -lzwrócił 90 paczek.
slm
6

Najłatwiejszym i działającym przez długi czas jest:

yum-debug-dump => gives file.

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

... który działa podobnie do polecenia get / set selections dpkg, AIUI. Pamiętaj również, że jeśli odtwarzasz historię, możesz użyć:

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

... zamiast samodzielnie go analizować.

James Antill
źródło
3

Zainspirowany slm „s odpowiedź Doszedłem z następującym yum historyrozwiązaniem opartym:

Uzyskaj całą szczegółową historię wszystkich transakcji instalacji yum (tj. Brak aktualizacji), z wyjątkiem tych wykonanych w ramach działań instalatora początkowego (transakcje 1 i 2 w moim systemie, przypisane do użytkownika „System”):

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

Filtruj jawnie zainstalowane pakiety i odcinaj prefiksy wersji.

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

Potrzebne jest brzydkie wyrażenie regularne, aby dopasować wszystkie rodzaje sufiksów wersji.

Wyniki wyglądają całkiem dobrze w moim systemie.

Porównanie z repozytorium ansatz (w moim systemie):

metoda # pakiety
―――――――――――――――――――――――――
repozytorium 569
repoquery-2nd 216
mniam historia 214

(Przekazałem wyniki repozytorium przez sort -u)

Dlaczego są różnice? Ponieważ repoquery obejmuje wszystkie pakiety z transakcji 1 i 2, tj. Wszystkie pakiety, które zostały zainstalowane przez instalator Fedory. To wyjaśnia, dlaczego repoquery obejmuje wspomniane pakiety xorg-x11-drv-mga i przyjaciół.

Porównanie 2. repoquery i yum-history pokazuje, że repoquery 2. jest dokładniejsze - nie zawiera niektórych już usuniętych pakietów. Ponadto zawiera kilka (2 w moim systemie) pakietów z operacji „mniam aktualizacja”, jak się wydaje.

Ostrzeżenie

Powyższa metoda oparta na historii wyświetla tylko wszystkie jawnie zainstalowane pakiety przez cały okres istnienia systemu. Nie równoważy tych pakietów, które zostały usunięte w późniejszej transakcji. Dlatego ta metoda wymaga ręcznego ustalania wyników i powinna być stosowana tylko w systemach, w których repoquerynie jest dostępna.

maxschlepzig
źródło
Miły sposób na skorzystanie z obu naszych odpowiedzi! Dałbym ci więcej niż +1, gdybym mógł za ostateczne rozwiązanie + ładne porównanie różnych sposobów, aby to zrobić.
slm
2

Mam starszą wersję Fedory (14), więc moje yum zawiera mniej bogatą wersję yum, ale możesz rzucić okiem na tę yum historyfunkcję. Wierzę, że możesz uzyskać informacje, których szukasz z tego polecenia.

lista historii

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

Możesz wrócić do pierwszej transakcji, przekazując listę numerów do 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

informacje o historii

Poniżej pokazano, co zostało zainstalowane w ramach pierwszej transakcji 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

Zauważ, w jaki sposób yum informuje, czy pakiet został jawnie zainstalowany, czy zainstalowany, ponieważ był potrzebny przez zależność. Możesz przeanalizować te informacje i uzyskać listę pakietów, które zostały jawnie zainstalowane.

slm
źródło
Dodałem odpowiedź na podstawie twojego yum historypomysłu, porównuje ona również wyniki z repoquerymetodą opartą na pomiarze. Jako efekt uboczny rozszerzyłem moją odpowiedź dotyczącą repoquery.
maxschlepzig
1
dnf repoquery --qf "%{name}" --userinstalled > userinstalled.txt
Flo
źródło
1
Kiedy patrzysz na pozostałe 5 odpowiedzi tutaj, co widzisz, co różni się w twojej odpowiedzi? Nie ma absolutnie żadnego wyjaśnienia, dlaczego lub w jaki sposób twoja odpowiedź jest lepsza od innej. Byłoby dobrze, gdybyś mógł podać opis swojej odpowiedzi obejmujący te rzeczy.
Stephen Rauch,
@StephenRauch, to polecenie nie jest uwzględnione w innych odpowiedziach, ponieważ jest to najnowszy dodatek dnf. --userinstalledPrzełącznik został właśnie dodany do DNF w maju . Przetestowałem to i daje dokładne wyniki. Modulo pakiety kernel / kernel-core / kernel-moduły, które tak naprawdę nie są instalowane przez użytkownika. Zawiera także wszystkie *-debuginfopakiety - ale w razie potrzeby można je łatwo odfiltrować.
maxschlepzig
@maxschlepzig, dziękuję za informację zwrotną, ale tak naprawdę było to trochę retoryczne pytanie, próbujące wyszkolić / zachęcić osobę udzielającą odpowiedzi do wyjaśnienia tego w odpowiedzi.
Stephen Rauch,
@StephenRauch, wystarczy, pewna edycja byłaby z pewnością odpowiednia i pozwoliłaby mi oznaczyć ją jako zaakceptowaną odpowiedź.
maxschlepzig
0

Do opakowań lista ty zainstalowanych, spróbuj to jedno-liner :

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

Wynik:

# 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: nie pokazuje zależności

PS2: jest posortowany alfabetycznie

PS3: nie pokazuje, czy pakiet został usunięty później

Fernando Fabreti
źródło
-1

Co zrobiłem (zapomniałem szczegółów, a ja jestem leniwym dupkiem, więc ...

Pobierz wszystkie zainstalowane pakiety: rpm -qa > file

Posługiwać się sed(1) aby pozbyć się numerów wersji i tym podobnych (zachowaj architekturę, jeśli jest wymagana). Wymagało to kilku iteracji, aby wszystko było w porządku, chcesz zastąpić ostatni odcinek -[0-9.]-[0-9].fc23lub podobny niczym, ale są też zabawne „numery” wersji.

Po normalnej instalacji wykonaj yum -y install $(< file) (lub dnf, w razie potrzeby).

Dostaniesz opadające pakiety, które już nie istnieją, zmieniły nazwę lub zostały zastąpione innymi.

vonbrand
źródło
Ok, ale spowoduje to oznaczenie wszystkich wcześniej zainstalowanych pakietów jako zintegrowanych z użytkownikiem na hoście docelowym. Nawet jeśli pierwotnie były instalowane tylko jako zależność.
maxschlepzig