Une place pour une véritable innovation. Partagez vos propres utilitaires créés avec la communauté Manjaro.
Questions et discussions sur la programmation et le codage.
Répondre

Jouer à frankenstein avec pacman

#1Messageil y a 2 ans

:bjr: Bonjour

Ce week-end, après avoir vu un commit aur, j'ai décidé de perdre une heure de mon temps à jouer aux apprentis sorcier


Attention : Comme le Docteur F. je ne suis arrivé qu'a un monstre fait de bout de ficelles et aucunement à un résultat "viable" ;) Mais il ne coûte rien de partager mes élucubrations ?


Aur fournit depuis quelques jours un fichier avec la liste des paquets disponibles avec un peu plus de détails que l'unique nom du paquet ...
Idée FOLLE : transformer ce fichier en base de donnée pacman ... Si cela est possible alors je vais pouvoir consulter aur depuis pacman !!! :lolfou

Big spoiler (pour éviter de vous faire perdre du temps à lire le reste): au final, certainement pas possible d'installer avec cette technique : donc on ne remplace pas un aur helpeur ;) et la consultation ? pas génial - même pas passable :mrgreen:

--------------------------------

Le nouveau fichier disponible par aur est un fichier json au format:

{
"warning": "This is a experimental! It can be removed or modified without warning!",
"columns": ["ID", "Name", "Version", "Description", "URL", "PackageBaseID"], 
"data": [ 

[182473, "mkinitcpio-welcomemessage", "0.0.0-1", "mkinitcpio hook to show some message on boot", "https://aur.archlinux.org/packages/mkinitcpio-welcomemessage/", 93686], 
[182745, "dvbsky-firmware", "20141128-1", "Firmware for DVBSky cards/boxes", "http://www.dvbsky.net/Support_linux.html", 67834],
...
]
}
experimental! It can be removed or modified without warning!
Au moins c'est clair

Donc ici, l'idée démoniaque est de convertir ce fichier en base de donnée pacman ; une base de donnée pacman est une archive (.db) qui contient un répertoire par paquet et dans chaque répertoire un fichier texte `desc` (la même chose que notre base de donnée locale pacman d nos paquets installés)

Le fichier json comporte 77 000 enregistrements, il faut donc créer autant de répertoires et fichiers puis intégrer tout cela dans une archive.
ici, j'utilise un script python : c'est très lent mais pour un test cela suffit amplement (dans la vrai vie, il faudrait re-générer cette archive toutes les 10 minutes (avec 4Mo à télécharger)... donc choisir un autre language)

Le script (aurtodb.py):

#!/usr/bin/env python

import sys
import requests
import tarfile
from pathlib import Path

url = "https://aur.archlinux.org/packages-teapot.json.gz"
'''
{
 "warning": "This is a experimental! It can be removed or modified without warning!",
 "columns": ["ID", "Name", "Version", "Description", "URL", "PackageBaseID"],
 "data": [ ... ]
}
'''

req = requests.get(url, allow_redirects=True)
pkgs = req.json()['data']
print(f"{len(pkgs)} aur packages")

Path("/tmp/aur.db").mkdir()

for pkg in pkgs:
    pkg[1] = pkg[1].strip()
    pkg[2] = pkg[2].strip()
    if pkg[2].count('-') > 1:   # fix 7 files in 77000 ...
        print(f'Error in version "{pkg[1]}" : {pkg[2]}', file = sys.stderr)
        pkg[2] = pkg[2].replace('-', '.', 1)
    dir = f"/tmp/aur.db/{pkg[1]}-{pkg[2]}"
    Path(dir).mkdir()
    fdesc = Path(f"{dir}/desc")
    fdesc.write_text(f"%NAME%\n{pkg[1]}\n\n%VERSION%\n{pkg[2]}\n\n%DESC%\n{pkg[3]}\n\n%URL%\n{pkg[4]}")

Path("aur.db").unlink()
with tarfile.open("aur.db", "w:gz") as tar:
    for fn in Path("/tmp/aur.db").glob('*/desc'):
        print(fn)
        tar.add(fn, arcname=fn.relative_to("/tmp/aur.db"))
        Path(fn).unlink()
        Path(fn.parent).rmdir()
Path("/tmp/aur.db").rmdir()

print(f"{len(pkgs)} aur packages")
print('sudo pacman -Sy ; pacman -Sl aur')
ps: archive générée avec quelques erreurs, mais si ce n'ai pas pour une utilisation régulière, cela n'est pas trop grave (le monstre du Docteur F. n'était pas parfait il me semble)

Clairement trop lent pour petite machine ?
Une version extrêmement plus rapide en nim (traduit en C puis compile)

import std/strformat, httpclient, strformat, strutils, tables, zippy, zippy/ziparchives, json

# nimble install zippy
# nim compile -d:ssl -r aurToDb.nim

let client = newHttpClient()
client.headers = newHttpHeaders({"Accept-Encoding": "gzip"})

let
  response = client.request("https://aur.archlinux.org/packages-teapot.json.gz")
  compressed = response.body
  uncompressed = uncompress(response.body)
  
echo &"compressed size: {compressed.len} uncompressed size: {uncompressed.len}"

let archive = ZipArchive()

let pkgs = parseJson(uncompressed)["data"]
var i, j = 0
for pkg in pkgs:
    i += 1
    var name = pkg[1].getStr().strip()
    var ver = pkg[2].getStr().strip()
    var desc = pkg[3].getStr()

    if ver.count('-') > 1:
        #ver = ver.replace('-', '.', 1)
        echo name, ": ", ver
        for i, c in ver:
            if c == '-':
                ver[i] = '.'
                echo name, ": ", ver, "\n"
                break
    var filename = fmt"{name}-{ver}/desc"

    archive.contents[filename] = ArchiveEntry(
        contents: fmt("%NAME%\n{name}\n\n%VERSION%\n{ver}\n\n%DESC%\n{desc}\n")
    )
    #if i > 235:
    #    break

archive.writeZipArchive("aur.db")
------------
Configurer pacman :
Ajouter un nouveau dépôt "aur" et simplement le faire pointer vers le répertoire qui contient notre archive générée aur.db (et donc aussi notre script)
ps: attention, le répertoire ne doit pas avoir d'espace
par exemple, copier notre script dans: ~/aur/

On ajoute donc à la fin de /etc/pacman.conf

[aur]
# changer "MON_LOGIN" pour un autre ;)
Server = file:///home/MON_LOGIN/aur/
Ici, nous demandons à pacman de télécharger le fichier aur.db qui est disponible dans /home/MON_LOGIN/aur/

Dans ce répertoire:
- on génère la base de donnée: python aurtodb.py
- on update la base de donnée pacman: sudo pacman -Sy
Maintenant nous avons un dépôt 'aur' dans pacman ! donc il est disponible pour consultation comme les autres dépôts officiels
pacman -Sl aur (liste tous les paquets de ce dépôt : 77000)
pacman -Ss pamac : va lister aussi les paquets aur dans la réponse (ok aussi avec pamac gui)

pacman -Ss pamac
...
aur/archlinux-appstream-data-pamac 20210929-1
    Arch Linux application database for AppStream-based software centers (Fixed for pamac-aur and pamac-all packages)
aur/libpamac 11.1.0-1
    Library for Pamac package manager based on libalpm
aur/libpamac-aur 11.1.0-2
    Pamac package manager library based on libalpm
aur/libpamac-flatpak 11.1.0-1
    Library for Pamac package manager based on libalpm - flatpak support enabled
aur/libpamac-full 1:11.1.0-1
    Library for Pamac package manager based on libalpm - flatpak and snap support enabled
aur/libpamac-full-dev 11.1.0beta2-1
    Library for Pamac package manager based on libalpm - flatpak and snap support enabled - development version
aur/pamac-all 10.2.1-1
    A Gtk3 frontend for libalpm (everything in one package - snap, flatpak, appindicator)
aur/pamac-all-git 1:10.2.0beta.r0.gefeee38-3
    A Gtk3 frontend for libalpm (everything in one package - snap, flatpak, appindicator)
aur/pamac-aur 10.2.1-2
    A Gtk3 frontend, Package Manager based on libalpm with AUR and Appstream support
aur/pamac-aur-git 10.2.1.r0.gc84f52c-1
    A Gtk3 frontend for libalpm - git version
aur/pamac-classic 7.3.0-2
    A Gtk3 frontend for libalpm - classic version
aur/pamac-cli 10.1.2-1
    Pamac cli frontend for libalpm
MAIS
pour pacman 'aur' est un dépôt donc il va essayer d'installer via notre miroir et ... il est clair que aur n'est pas un miroir de paquets. Donc il va y avoir erreur pour toute tentative d'installation

---------------------

Nous avons donc ajouté à pacman un dépôt fictif juste pour de la recherche dans aur.
cela est super pratique puisqu'il faut le régénérer plusieurs fois par jour et que dans pamac.conf, il faut l'activer uniquement lorsque nous faisons une recherche et ne pas oublier de le dé-activer (mettre en commentaires) dès que nous désirons faire un update ou une installation.

Jouer à frankenstein avec pacman

#2Messageil y a 2 ans

:bjr:
Voila, est sorti la spécification officielle pour aur :fete:
papajoke a écrit : il y a 2 ans

"warning": "This is a experimental! It can be removed or modified without warning!",
Fini l'expérimentation chez aur avec le fichier packages-teapot, place à la solution officielle. Aur propose maintenant 2 nouveaux fichiers qui représentent la database aur
Cela devrait permettre aux "aur helpeur" , nos assistants aur, de fonctionner plus comme pacman : Télécharger une (grosse) base de donnée et de ne plus consulter aur pour chaque demande de renseignement. Donc plus de risque d'être bloqué par aur avec son ip puisque avec cette future solution on ne consulte plus rpc

Est disponible 2 formats de 7 et 9Mo à télécharger, cette base de donnée est mise à jour toutes les 5 minutes sur le serveur aur

Cette fois, pas de truc bizarre :rigole: Un vrai petit utilitaire aur :o
Le petit script pour tester cette base de donnée (que de la consultation ici ;) ) avec une utilisation très limitée:

aur-db.py -h
./script command [value]
    check             : update available for my aur package ?
    new               : list new entries since this prev command
    out               : list Out of Date
    list              : list last Updates
    search [name]     : Search in database
    cat    [pkg..pkg] : Display package info
    count             : count packages in database
    pop               : list sort by popularity
    --r               : remove database
    --d               : force download database
La base de donné est téléchargée dans /tmp/, donc par défaut, ce script ne la télécharge qu'à chaque boot (existe --d pour forcer un nouveau download)


Image
résultat de la commande check, je n'ai que powerline à mettre à jour , paquets en rouge ne sont pas(/plus) présent dans aur
ps: comparaison des versions uniquement si pyalpm est installé (--asdeps)...

le code
Répondre