[HOWTO] Nettoyer les distfiles et les packages avec eclean
Posted: Thu Sep 15, 2005 2:39 pm
Introduction
Je n'apprendrai rien à personne en vous disant que le répertoire /usr/portage/distfiles, où emerge télécharge les sources de vos paquets, à une facheuse tendance à enfler considérablement avec le temps. Même chose pour /usr/portage/packages, où emerge stock les paquets binaires, pour les utilisateurs des FEATURES flags "buildpkg" ou "buildsyspkg". C'est un petit désagrément vieux comme Gentoo...
Seulement voilà, le nettoyage de ses répertoire ne peut pas raisonnablement être fait à coup de "rm -rf", parcequ'il serait dommage d'effacer par exemple les sources du dernier Xorg quand on est susceptible d'en avoir besoin le lendemain pour une nouvelle révision (-rX) de l'ebuild. N'oublions pas que quand on re-télécharge un fichier, on abuse de la bande passante des mirroirs, qui n'est pas gratuite et donc difficile à obtenir pour Gentoo. De même pour les paquets binaires, on peut avoir envie de faire du ménage sans pour autant supprimer celui de sauvegarde de notre GCC, qui peut si bien dépanner parfois.
Pour faire ce ménage de façon plus parcimonieuse, il existe depuis longtemps de nombreux scripts officieux, écrits par des utilisateurs : on en trouve plein ici pour les distfiles, ou encore yacleaner qui s'occupe aussi des paquets binaires, et puis plein d'autres qui trainent ici et là et que j'ai oublié. Mais il n'y en avait jusque alors aucun d'officiel... jusqu'à l'intégration récemment de eclean dans gentoolkit-0.2.1_pre6. C'est celui là que je vais un peu vous présenter, parce que pour l'avoir écrit je le connais bien, et puis parce que c'est le meilleurs d'abord, nah.
Installation
Rien de bien compliqué pour l'installation, maintenant que la bête est incluse dans gentoolkit. Si vous êtes en ~arch, vérifiez juste que avez bien gentoolkit-0.2.1_pre7 (la version de la _pre6 ne fonctionnant pas avec portage-2.0.52). Si vous êtes en stable, alors votre gentoolkit doit encore en être à la 0.2.0... N'hésitez pas à passez ce paquet en ~arch, il ne va pas vous manger :
À noter qu'à partir de maintenant, je n'ai pas grand chose à ajouter par rapport à «man eclean». Mais bon, je sais que les manpages en anglais, certains les lisent avec d'enthousiasme que les posts du forum francophone, alors allons y quand même...
Invocation, principaux modes de nettoyage
La commande de base de eclean est la suivante : Ici, <action> peut être soit distfiles, soit packages, suivant ce que vous souhaitez nettoyer. On dispose aussi de deux commandes raccourcies : eclean-dist et eclean-pkg, qui positionnent l'action respectivement à distfiles ou packages, et qui prennent en paramètres les options globales ou spécifiques, sans ordre particulier.
Au niveau des options globales, je ne m'étendrai pas bien longtemps sur les plus évidentes, que voici :
Les autres options globales par contre sont plus intéressantes, parce qu'elles agissent sur les choix que eckean va faire en matière d'effacement, bref elles déterminent ce qu'est cette "parcimonie" du nettoyage.
Voilà déjà comment eclean fonctionne sans option : il regarde l'ensembles des ebuilds disponibles (dans l'arbre et dans vos overlays), dans toutes leurs versions, et protège tout ce qui les concerne. C'est à dire que pour l'action distfiles, si vous avez d'installé xorg-x11-6.8.99.x mais que les les sources du 6.8.3 sont encore là, elles seront protegées. De même pour l'action packages, si vous tournez en gcc-3.4 mais avez encore un binaire de gcc-3.3.5, il sera protégé. Bref, ce mode par défaut est le plus conservateur, puisqu'il suppose que tout ce qui est accessible est susceptible d'être encore installé, et gardera donc aussi des fichiers pour d'éventuels downgrades, ou la réinstallation de paquets qu'on avait précédemment supprimés, etc.
Viens ensuite l'option "--destructive" : Avec cette option, eclean va faire un nettoyage plus agressif, et ne conserver que les fichiers concernés par les ebuilds des paquets installés, dans leur version exacte. Si vous avez xorg-x11-6.8.99-15, seule les sources de cette versions exactement seront préservée. De même, si vous avez plusieurs paquets binaires de GCC, mais que seul le 3.4.4-r1 est installé, alors seul le paquet binaire de cette version sera conservé. Au niveau distfiles donc, on ne conserve que de quoi faire un "emerge -e world", ou encore de quoi voir venir les futures "revision bump" des ebuilds (les version-rX). Et au niveau packages, on garde de quoi réparer ce qu'on pourrait malencontreusement corompre sur notre système, mais pas de quoi retourner d'une version en arrière.
Viens enfin l'option "--package-names", utilisable uniquement en plus de "--destructive" : Avec cette options, le nettoyage sera un peu un intermédiaire entre les deux modes précédents : on va conserver ce qui concerne toutes les versions disponibles des paquets installés, et donc conserver ce qui pourrait par exemple servir à faire un downgrade de paquet (comme pour le mode par défaut), mais on va quand même effacer tout le reste. Donc si vous avez encore les sources du dernier KDE mais que depuis vous l'avez virer et êtes passés à GNOME, elles seront effacées.
À noter que les autres scripts de nettoyage (comme yacleaner) utilisent tous, à ma connaissance, une logique qui correspond au mode le plus déstructif d'eclean ("--destructive" sans l'option "--package-names").
Options d'exclusion
En plus de ces trois principaux modes de fonctionnement, on peut utiliser quelques autres options pour affiner la politique de nettoyage.
En option globale, donc valable autant pour les paquets binaires que pour les distfiles, on dispose de "--time-limit" : Bon, pas besoin d'épiloguer là dessus, ça permet d'exclure du nettoyage les fichiers les plus récents. C'est une bonne précaution par exemple pour les gens qui bricolent un peu des ebuilds eux même : on peut facilement avoir dans ses distfiles des sources pour un ebuild qu'on va mettre quelques jours à finir avant de définitivement l'installer, et cette option permettra de les protéger (c'est surtout pertinent pour les gens qui lanceront eclean régulièrement depuis leur crontab).
Pour les distfiles, et uniquement pour eux (donc dans les options spécifiques à l'action distfiles), on dispose aussi de ça :
Le "-f" permet donc de protéger, malgré un --destructive, les fichiers distfiles qu'on a dû télécharger à la main (comme les JDK de Sun par exemple). Quant au "-s", il permet de protéger les plus gros fichiers distfiles. Disons que ces deux options sont des précautions supplémentaires pour éviter d'effacer par mégarde des fichiers particulièrement galère à re-télécharger.
Voilà, c'est presque fini pour les options. Vous aurez noté qu'il n'existe pas d'option spécifique à l'action packages donc.
Fichiers d'exclusion
Un peu dans le même esprit que les options d'exclusion, les "fichiers d'exclusion" sont deux fichiers de configuration qui permettent aussi d'affiner le travail d'eclean pour des cas particuliers. On va pouvoir explicitement y lister des choses à exclure du nettoyage.
Par défaut, ces fichiers fichiers sont /etc/eclean/distfiles.exclude et /etc/eclean/packages.exclude, respectivement pour les actions distfiles et packages. Mais on peut changer ce chemin avec cette option : C'est particulièrement utile si vous voulez temporairement ignorer votre fichier d'exclusion habituel : il suffit de donner /dev/null comme chemin.
Dans ces fichiers, on peut lister des noms de paquets (noms complets avec la catégorie, comme "app-shells/bash" par exemple) : les binaires ou distfiles de ce paquet seront alors protégés, même en --destructive. Les syntaxes avec version, comme ">=app-shells/bash-3" ne sont par contre pas supportées.
On peut aussi lister des noms de catégories ("sys-apps", ou éventuellement "sys-apps/*", mais c'est vraiment juste pour faire joli) : les binaires ou distfiles de tous les paquets de cette catégorie seront alors protégés. Dans ce cas, on peut alors aussi exclure certains paquets particuliers de la catégorie protegée : par exemple, "!sys-apps/portage" supprimera le paquet "sys-apps/portage" de la protection dont jouissent les autres paquets de "sys-apps".
Il faut savoir aussi que :
- les lignes blanches ou celles commençant par un "#" sont ignorées ;
- on ne liste qu'un élément par ligne.
À noter enfin que dans le fichier d'exclusion des distfiles, on peut donner des noms de fichiers sources à protéger, comme "OOo_1.1.4_source.tar.gz".
Personnellement, je trouve cette fonctionnalité utile surtout pour la protection des paquets binaires : on peut lister dans son packages.exclude les catégories des paquets les plus critiques comme sys-apps, sys-devel, etc., pour conserver plus de versions des binaires de ces paquets. On peut même envisager d'y lister tous les paquets de "system", avec une commande dans ce style :
Exemples d'utilisation
Allez, juste pour clarifier un peu les choses, quelques exemples... (je reprends ceux que j'avais mis dans la page man) :
- Effacer uniquement les distfiles complètement obsolètes, avec confirmation interactive :
- Vérifier quels seraient les paquets binaires complètement obsolètes à effacer, dans un terminal sans couleur :
- Effacer les paquets binaires des logiciels qui ne sont pas installés sur le système :
- Effacer tous les distfiles, saufs ceux des paquets installés (dans cette version exacte), ceux qui ont moins d'un mois, ceux qui sont à télécharger manuellement, et ceux qui font plus de 50 Mo :
- Dans une crontab, nettoyer silencieusement les paquets binaires dans le mode le plus conservateur, et ensuite les distfiles en mode destructif mais en protégeant ceux vieux de moins d'une semaine (l'action s'exécutera tous les dimanches à 1H du matin) :
FAQ
Fichtre, mais c'est super lent !
Oui et non, ça dépend...
Pour l'action packages, on sait toujours sur quels paquets travailler, puisque ce sont ceux qui sont dans /usr/portage/packages. Donc là, en général le temps d'exécution devrait être très raisonnable (modulo que l'utilisation des modules python de portage est toujours un peu lourde avant même qu'on ait voulu faire quoi que ce soit. Cf. le temps que "emerge" met à afficher le "These are the packages that I would merge, in order:" la première fois que vous l'utiliser après un reboot tout frais).
Pour l'action distfiles, c'est plus compliqué... Dans le mode le plus conservateur, celui par défaut, on est obligé de lister tous les fichiers sources réferencés dans l'arbre portage. Ça fait des dizaines de milliers d'ebuilds à acceder, et donc oui, c'est très lent (plusieurs minutes). Au contraire, en mode "--destructive", on n'a que quelques centaines d'ebuilds à traiter (ceux installés), et là l'exécution est très largement plus rapide. Quant aux autres options, certaines influent aussi : --package-names ralentit les choses (accès à toutes les versions des paquets installés, au lieu d'une seul en --destructive tout court), mais pas au point du mode par défaut. Par contre --fetch-restricted nous fait à nouveau retomber aux piètres performances du mode par défaut, puisqu'il faut chercher les ebuilds ainsi marqués dans l'ensemble de l'arbre Portage.
Eclean m'a effacé mon helpcontent_33_unix.tgz, alors qu'il sert pour OpenOffice !
Voilà un exemple de fichier qui est utilisé par un ebuild, mais qui n'y est pas référencé dans les fichiers sources nécéssaires (pour ceux qui connaissent pas, c'est le fichier d'aide localisé en français, que l'ebuild d'OOo utilisera si il le trouve). Eclean ne peut pas grand chose contre ça, c'est un défaut de l'ebuild. Par contre, en ajoutant "helpcontent_33_unix.tgz" à /etc/eclean/distfiles.exclude, on contourne ce problème.
Eclean devrait permettre le nettoyage de /var/tmp/portage, ou du PORT_LOGDIR, etc.
Bof bof... Pour ces deux là au moins, je ne vois pas trop l'intérêt de faire ça depuis eclean. N'importe quel one-liner à coup de "find" et "rm", ou encore "tmpreaper" ou "tmpwatch", font plutôt bien l'affaire. Le truc, c'est que je ne veux mettre dans eclean que des choses qui ont effectivement besoin d'accèder à l'API de portage pour être intelligement nettoyées. Enfin bon, si vous avez des arguments, je ne suis pas non plus fermé aux features requests hein...
The end...
Pfiou... bah voilà, v'ai encore verbé
En espérant que vous trouverez ce programme utile...
Je n'apprendrai rien à personne en vous disant que le répertoire /usr/portage/distfiles, où emerge télécharge les sources de vos paquets, à une facheuse tendance à enfler considérablement avec le temps. Même chose pour /usr/portage/packages, où emerge stock les paquets binaires, pour les utilisateurs des FEATURES flags "buildpkg" ou "buildsyspkg". C'est un petit désagrément vieux comme Gentoo...
Seulement voilà, le nettoyage de ses répertoire ne peut pas raisonnablement être fait à coup de "rm -rf", parcequ'il serait dommage d'effacer par exemple les sources du dernier Xorg quand on est susceptible d'en avoir besoin le lendemain pour une nouvelle révision (-rX) de l'ebuild. N'oublions pas que quand on re-télécharge un fichier, on abuse de la bande passante des mirroirs, qui n'est pas gratuite et donc difficile à obtenir pour Gentoo. De même pour les paquets binaires, on peut avoir envie de faire du ménage sans pour autant supprimer celui de sauvegarde de notre GCC, qui peut si bien dépanner parfois.
Pour faire ce ménage de façon plus parcimonieuse, il existe depuis longtemps de nombreux scripts officieux, écrits par des utilisateurs : on en trouve plein ici pour les distfiles, ou encore yacleaner qui s'occupe aussi des paquets binaires, et puis plein d'autres qui trainent ici et là et que j'ai oublié. Mais il n'y en avait jusque alors aucun d'officiel... jusqu'à l'intégration récemment de eclean dans gentoolkit-0.2.1_pre6. C'est celui là que je vais un peu vous présenter, parce que pour l'avoir écrit je le connais bien, et puis parce que c'est le meilleurs d'abord, nah.
Installation
Rien de bien compliqué pour l'installation, maintenant que la bête est incluse dans gentoolkit. Si vous êtes en ~arch, vérifiez juste que avez bien gentoolkit-0.2.1_pre7 (la version de la _pre6 ne fonctionnant pas avec portage-2.0.52). Si vous êtes en stable, alors votre gentoolkit doit encore en être à la 0.2.0... N'hésitez pas à passez ce paquet en ~arch, il ne va pas vous manger :
Code: Select all
% echo app-portage/gentoolkit >> /etc/portage/package.keywords
% emerge gentoolkitÀ noter qu'à partir de maintenant, je n'ai pas grand chose à ajouter par rapport à «man eclean». Mais bon, je sais que les manpages en anglais, certains les lisent avec d'enthousiasme que les posts du forum francophone, alors allons y quand même...
Invocation, principaux modes de nettoyage
La commande de base de eclean est la suivante :
Code: Select all
% eclean [options globales] <action> [options spécifiques à l'action]Au niveau des options globales, je ne m'étendrai pas bien longtemps sur les plus évidentes, que voici :
Code: Select all
-C, --nocolor - désactive l'affichage en couleurs
-i, --interactive - demande une confirmation pour les effacements
-p, --pretend - affiche ce qui serait fait, mais ne le fait pas
-q, --quiet - mode silencieux, n'affiche que les erreurs
-h, --help - affiche l'aide d'eclean
-V, --version - affiche la version d'ecleanVoilà déjà comment eclean fonctionne sans option : il regarde l'ensembles des ebuilds disponibles (dans l'arbre et dans vos overlays), dans toutes leurs versions, et protège tout ce qui les concerne. C'est à dire que pour l'action distfiles, si vous avez d'installé xorg-x11-6.8.99.x mais que les les sources du 6.8.3 sont encore là, elles seront protegées. De même pour l'action packages, si vous tournez en gcc-3.4 mais avez encore un binaire de gcc-3.3.5, il sera protégé. Bref, ce mode par défaut est le plus conservateur, puisqu'il suppose que tout ce qui est accessible est susceptible d'être encore installé, et gardera donc aussi des fichiers pour d'éventuels downgrades, ou la réinstallation de paquets qu'on avait précédemment supprimés, etc.
Viens ensuite l'option "--destructive" :
Code: Select all
-d, --destructive - conserve le minimum nécéssaire à une réinstallationViens enfin l'option "--package-names", utilisable uniquement en plus de "--destructive" :
Code: Select all
-n, --package-names - protège toutes les versionsÀ noter que les autres scripts de nettoyage (comme yacleaner) utilisent tous, à ma connaissance, une logique qui correspond au mode le plus déstructif d'eclean ("--destructive" sans l'option "--package-names").
Options d'exclusion
En plus de ces trois principaux modes de fonctionnement, on peut utiliser quelques autres options pour affiner la politique de nettoyage.
En option globale, donc valable autant pour les paquets binaires que pour les distfiles, on dispose de "--time-limit" :
Code: Select all
-t, --time-limit=<time> - ne pas effacer les fichiers datant de moins de <time>
<time> est une durée: "1y" pour "one year" (1 an), "2w" pour "two weeks" (2 semaines), etc.
Les unités sont : y (years), m (months), w (weeks), d (days) et h (hours).Pour les distfiles, et uniquement pour eux (donc dans les options spécifiques à l'action distfiles), on dispose aussi de ça :
Code: Select all
-f, --fetch-restricted - protège les fichiers "fetch-restricted" (en mode --destructive)
-s, --size-limit=<size> - prtège les fichiers d'une taille supérieure à <size>
<size> est une taille de fichier : "10M" pour "dix megaoctets", "200K" pour
"deux cent kilooctets", etc. Les unités sont : G, M, K et B.
Voilà, c'est presque fini pour les options. Vous aurez noté qu'il n'existe pas d'option spécifique à l'action packages donc.
Fichiers d'exclusion
Un peu dans le même esprit que les options d'exclusion, les "fichiers d'exclusion" sont deux fichiers de configuration qui permettent aussi d'affiner le travail d'eclean pour des cas particuliers. On va pouvoir explicitement y lister des choses à exclure du nettoyage.
Par défaut, ces fichiers fichiers sont /etc/eclean/distfiles.exclude et /etc/eclean/packages.exclude, respectivement pour les actions distfiles et packages. Mais on peut changer ce chemin avec cette option :
Code: Select all
-e, --exclude-file=<path> - chemin du fichier d'exclusion Dans ces fichiers, on peut lister des noms de paquets (noms complets avec la catégorie, comme "app-shells/bash" par exemple) : les binaires ou distfiles de ce paquet seront alors protégés, même en --destructive. Les syntaxes avec version, comme ">=app-shells/bash-3" ne sont par contre pas supportées.
On peut aussi lister des noms de catégories ("sys-apps", ou éventuellement "sys-apps/*", mais c'est vraiment juste pour faire joli) : les binaires ou distfiles de tous les paquets de cette catégorie seront alors protégés. Dans ce cas, on peut alors aussi exclure certains paquets particuliers de la catégorie protegée : par exemple, "!sys-apps/portage" supprimera le paquet "sys-apps/portage" de la protection dont jouissent les autres paquets de "sys-apps".
Il faut savoir aussi que :
- les lignes blanches ou celles commençant par un "#" sont ignorées ;
- on ne liste qu'un élément par ligne.
À noter enfin que dans le fichier d'exclusion des distfiles, on peut donner des noms de fichiers sources à protéger, comme "OOo_1.1.4_source.tar.gz".
Personnellement, je trouve cette fonctionnalité utile surtout pour la protection des paquets binaires : on peut lister dans son packages.exclude les catégories des paquets les plus critiques comme sys-apps, sys-devel, etc., pour conserver plus de versions des binaires de ces paquets. On peut même envisager d'y lister tous les paquets de "system", avec une commande dans ce style :
Code: Select all
% emerge -pe system | sed -n -e 's:^\[.*\] ::' -e 's:-[0-9].*::p' >> /etc/eclean/packages.excludeExemples d'utilisation
Allez, juste pour clarifier un peu les choses, quelques exemples... (je reprends ceux que j'avais mis dans la page man) :
- Effacer uniquement les distfiles complètement obsolètes, avec confirmation interactive :
Code: Select all
# eclean -i distfilesCode: Select all
# eclean -Cp packagesCode: Select all
# eclean-pkg -d -nCode: Select all
# eclean-dist -d -t1m -s50M -fCode: Select all
0 1 * * sun eclean -C -q packages ; eclean -C -q -d -t1w distfilesFAQ
Fichtre, mais c'est super lent !
Oui et non, ça dépend...
Pour l'action packages, on sait toujours sur quels paquets travailler, puisque ce sont ceux qui sont dans /usr/portage/packages. Donc là, en général le temps d'exécution devrait être très raisonnable (modulo que l'utilisation des modules python de portage est toujours un peu lourde avant même qu'on ait voulu faire quoi que ce soit. Cf. le temps que "emerge" met à afficher le "These are the packages that I would merge, in order:" la première fois que vous l'utiliser après un reboot tout frais).
Pour l'action distfiles, c'est plus compliqué... Dans le mode le plus conservateur, celui par défaut, on est obligé de lister tous les fichiers sources réferencés dans l'arbre portage. Ça fait des dizaines de milliers d'ebuilds à acceder, et donc oui, c'est très lent (plusieurs minutes). Au contraire, en mode "--destructive", on n'a que quelques centaines d'ebuilds à traiter (ceux installés), et là l'exécution est très largement plus rapide. Quant aux autres options, certaines influent aussi : --package-names ralentit les choses (accès à toutes les versions des paquets installés, au lieu d'une seul en --destructive tout court), mais pas au point du mode par défaut. Par contre --fetch-restricted nous fait à nouveau retomber aux piètres performances du mode par défaut, puisqu'il faut chercher les ebuilds ainsi marqués dans l'ensemble de l'arbre Portage.
Eclean m'a effacé mon helpcontent_33_unix.tgz, alors qu'il sert pour OpenOffice !
Voilà un exemple de fichier qui est utilisé par un ebuild, mais qui n'y est pas référencé dans les fichiers sources nécéssaires (pour ceux qui connaissent pas, c'est le fichier d'aide localisé en français, que l'ebuild d'OOo utilisera si il le trouve). Eclean ne peut pas grand chose contre ça, c'est un défaut de l'ebuild. Par contre, en ajoutant "helpcontent_33_unix.tgz" à /etc/eclean/distfiles.exclude, on contourne ce problème.
Eclean devrait permettre le nettoyage de /var/tmp/portage, ou du PORT_LOGDIR, etc.
Bof bof... Pour ces deux là au moins, je ne vois pas trop l'intérêt de faire ça depuis eclean. N'importe quel one-liner à coup de "find" et "rm", ou encore "tmpreaper" ou "tmpwatch", font plutôt bien l'affaire. Le truc, c'est que je ne veux mettre dans eclean que des choses qui ont effectivement besoin d'accèder à l'API de portage pour être intelligement nettoyées. Enfin bon, si vous avez des arguments, je ne suis pas non plus fermé aux features requests hein...
The end...
Pfiou... bah voilà, v'ai encore verbé
En espérant que vous trouverez ce programme utile...