upd: Fedora csomagok frissítése közvetlenül a build szerverről

Már régen írtam ezt a scriptet, de mostanában újra foglalkoztam vele, átesett egy ráncfelvarráson. Módosítottam a kódon, így beleírtam egy rakás bugot, de már nyugvópontra jutott, így ki merem post-olni.

Arról van szó, hogy nyughatatlan vagyok, s bizonyos csomagokat szeretek a hivatalos frissítés megjelenése előtt közvetlenül a Koji build szerverről frissíteni. Jellemzően ilyen a kernel, firefox, selinux-policy, meg ami épp eszembe jut. Különösen jól jön akkor, ha jelzek hibát a fejlesztők felé, elkészítik a javítást, kérik, hogy teszteljem, de még nem teszik bele a hivatalos repókba. Viszont a build szerverről már elérhető.

A szintaxisa igen egyszerű alapesetben, például:

upd firefox selinux-policy kernel{,-headers}

Ezek nem rpm csomagnevek, hanem azok a nevek, amelyek a build szerveren egyetlen source rpm-ből állítódnak elő. Tehát például a libreoffice esetében nem kell kiírni az alkomponensek neveit - libreoffice-calc, libreoffice-writer, és így tovább -, hanem elég a libreoffice név használata.

A program megnézi, hogy milyen csomagok vannak jelenleg a gépen, s ha van újabb a build szerveren, akkor csak azokat tölti le, amelyek a gépen is megvannak, csak régebbi változatban. Szóval nem kell megijedni, nem fogja feltenni valamelyik ázsiai nyelvi támogatást, ha az nincs már most is a gépen.

A program nem veszélyes, mert csak letölti a csomagokat, s átadja paraméterül a dnf-nek, az pedig interaktív, így ha látjuk, hogy valami nem gömbölyű, lehet 'N'-nel válaszolni arra, hogy megcsinálja-e a frissítést.

Mostanában két feature-t írtam bele: lehet alias-okat file-ban definiálni, továbbá a végrehajtás párhuzamos, több szálon futó, mert lassú volt. Hasonlóképp egy jelentős része awk-ban lett megírva, mert bash-ben lassú volt. Az egész egyetlen file, az awk scriptek bash-be vannak ágyazva. Illetve van egy alias konfig file-ja is.

Van három függősége: wget, aria2, parallel. Az utóbbi kettő nem kötelező, de ajánlott. A parallel-t első használat előtt

parallel --citation

paraméterrel kell futtatni, s értelemszerűen válaszolni a kérdésre.

Az alias fileban a hivatkozás lehet újabb alias, sőt, a rekurzív definíció is megengedett. Ezt az teszi lehetővé, hogy az alias-okhoz egy számlálót is definiáltam, s ha a hivatkozások száma eléri a 8-at, akkor az alias nevét, mint csomagnevet fogja felhasználni. Így aztán nem lesz végtelen ciklus a rekurzív definícióból, s nem kell megkülönböztetni az alias nevet a csomagnévtől. Illetve annyit érdemes tudni, hogy egy csomagnév csak egyszer kerül kifejtésre, a duplikálást a program ignorálja.

Korábbi kernelverziók törlésére a -k kapcsoló való. Az éppen aktuálisan futó, valamint a telepített legfrissebb verziót nem fogja törölni. Amúgy színnel jelöl, kérdez, de a végén a dnf is kérdez, szóval nyugalom. :)

A -v verziót ír, a -h helpet, bár az finoman szólva is szegényes. Csak egy szintaxis jelölés a használatról. A -n kapcsoló ignorálja azokat a csomagokat, amelyek rc verziók. Nem biztos, hogy beolvasztási időablakban lévő, vagy éppen kevéssel azutáni kernelre szeretnénk frissíteni. :)

/usr/local/bin/upd
/usr/local/etc/upd/upd_locsemege.aliases

Az alias file neve kötelezően ez: /usr/local/etc/upd/upd_${USER}.aliases
Tehát a felhasználó neve szerepeljen benne.

Egy lehetséges használat:

upd -k -n kernel se tb ff lo jre pa ghostscript hplip cups{,-pdf,-filters} ns glibc gcc lf

Ez persze feltételezi a példában megadott alias file-t.

Az upd script jogai root:root 0755, az alias file jogai $USER:users 0644, míg az őt tartalmazó könyvtáré praktikusan root:users 0775.

Erősen ajánlott sima felhasználóként futtatni. Majd, ha a dnf miatt kell, kéri a root jelszót.

Szerintem az egyes megoldásokból tanulni is lehet, például a párhuzamosítás vonatkozásában, vagy meg lehet nézni, hogy több dimenziós awk tömb elemein hogyan lehet végiggyalogolni, azokat címezni. Megtekinthető, awk-ból bash-be hogyan adok vissza egy rakás paramétert az eval használatával. Lényegében shell scriptet ír az awk, majd ezt a kimenetet értelmezi és hajtja végre az eval segítségével a shell. Meg persze öreg motorosoknak szörnyülködve lehet a hajukat tépni, hogy ezt miért éppen így. Mert így jutott eszembe. :)

Nézegessétek, használjátok ízlés szerint!

Két megjegyzés. Az angol nyelvű üzenetek olyanok, amilyenek. Magamnak írtam a programot, a nyelv nem erősségem. A másik, hogy ha valaki elgépel csomagnevet, az nem baj, a program közli, hogy nincs a repóban, de nem akad ezen fenn.

Hozzászólások

massage W 'Missing' "'$PARALLEL'" 'utility' 1>&2
:)

Egyébként ez koji nem működik rendes csomagtárolóként? Gondolom, hogy ez sok gondot megoldana.

Szerintem a Koji nem repó, de tévedhetek.
Nem tudom, csak felvetettem (nem vagyok Fedora-felhasználó).

De akkor egy kicsit továbbgondolva: ha bérelsz egy VPS-t, arra időközönként a téged érdeklő csomagokat leszeded, és gyakorlatilag egy repo-t építesz fel, amit a saját gépeden egyszerű csomagforrásként használsz. De lehet, hogy így bonyolultabb lenne.

Javult, van már v2.12-es változat. :)

A módosítás lényege, hogy amennyiben a gépen valamilyen oknál fogva frissebb csomag van, mint a build szerveren a legfrissebb csomag, úgy ilyenkor helyesen nem tölti le feleslegesen a régebbi csomagot, amelyről eddig a dnf látta csak be, hogy nem kell vele semmit sem csinálni.

Ilyen eset egyébként igen ritkán fordulhat elő. Vagy a build szerverről törölnek valamit - ennek érdemes utánajárni, mert lehet, annyira rossz volt, hogy inkább eltüntetik, de nekünk már megvan a csomag -, vagy másik repóból van újabb, mint a build szerverről a legújabb. Esetleg összevonnak csomagokat, mint történt ez most az nss, nss-softokn, nss-util nevűekkel.

Rövid ideig létezett v2.10 és v2.11 is, de a packagenamearch() függvényben találtam egy aztán még egy hibát, javítottam ezeket. Nem nyilvánvaló egy csomag verziószám nélküli nevét előállítani.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

v2.13

A "<" és ">" operátorok string esetén alfabetikus sorrend szerint mondanak igaz, vagy hamis értéket, nekem pedig version sort kell. Ezt javítja ez a változat. Tehát a 4.19.10-es kernel verzió nagyobb, mint a 4.19.9-es. Alfabetikusan nem volt az, ez okozta a problémát. Javítva.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

v2.14

Optimalizálás. Ha a két string egyenlő, nem kell version sort, amely awk-ból visszahívott shell pipe-ban hívott echo és sort, így itt lehet spórolni futásidőt.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

v2.16

Beleírtam a -x, vagy más néven --exclude kapcsolót. A -x utáni első paraméter lesz kizárva, az ezt követő paraméter megint include értelmű. Természetesen több exclude is megengedett, csak mindegyik elé ki kell írni a -x-et, vagy --exclude-ot. Az exclude sorrendje lényegtelen, a mindig az exclude a magasabb precedenciájú. Az exclude is lehet alias - akár rekurzívan is -, azt is kifejti, majd az így kapott neveket szépen kiszedi a feldolgozott pozitív - ha úgy tetszik, include - listából. Példa:

upd all -x kernel

Ez az alias file-ban all névre hallgató aliast kifejti, de a kernel nevű alias kifejtését kivonja a listából.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

v2.18

A sort -V meglepő működésére csináltam benne workaround-ot. Utólag kiderült, a sort dokumentáltan működik teljesen eszetlenül, így ez nem bug a részéről. Erről lehet, hogy írok majd.

Ezen kívül bevezettem a -w avagy --no-warning kapcsolót. Ez tiltja a warning üzenetek megjelenítését. Továbbá a -k kapcsolót használva a kernel-headers csomagot most már nem akarja eltávolítani akkor sem, ha annak verziószáma eltér az épp futó kernelétől. Lévén, a kernel-headers csomag frissül, abból nincs egyidejűleg több verzió a gépen.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE