Bitte Beachten: Dieser Blog wird hier nicht weiter geführt! Kommentare und neue Blogposts gibt es unter http://feitel.indeedgeek.de. Dort bitte auch neue Kommentare zu diesen Beiträge erstellen.

Montag, 10. März 2008

Fortgeschrittene Paketverwaltung mit Gentoo

Wer kennt das nicht. Man installiert ein Programm und irgend eine Kleinigkeit passt einem nicht. Sei es ein kleiner Bug oder ein fehlendes Feature. Oftmals kann man dies durch ein kurzes Patchen des Source Codes ausbügeln. Bisher unter Debian basierenden Distributionen war dies immer ein reißen Problem. Man musste manuell die Source herunterladen diese Patchen alle Abhängigkeiten herausfinden und installieren, Kompilieren und schließlich auch noch ein DEB-Paket erstellen und in die Paketverwaltung zurückführen. Wer das öfters machen muss wird wahnsinnig.

Bei der Installation von Gentoo bin ich auf ein richtig Cooles Feature gestoßen. Es gibt die Möglichkeit von Overlays. Das sind im Grunde weitere Repositories, die ebuilds, also die Gentoo-Pakete, enthalten. Richtig komfortabel wird dies da man über das Programm Layman einfach ein solches Repository bei sich einfügen kann, um dann daraus Software zu installieren. Im Prinzip wie bei Debian auch, nur das es viel anpassbarer ist. So besteht z.B. die Möglichkeiten das Repository über rsync, svn, git, bzr, etc. abzurufen und so zu aktualisieren. Im Gegensatz dazu sind auch Lokale Overlays möglich. Dabei legt man einfach ein Verzeichnis an und schmeißt die ebuilds die man installieren möchte einfach rein. Sehr komfortabel da man so kein Unterschied merkt ob diese Pakete nun Lokal in einem Overlay liegen oder aus dem offiziellen Portagetree kommen.

Hier ein kurzes Beispiel für ein Ebuild das aus einem lokalen Overlay installiert wird. Zuerst einmal das entsprechend Verzeichnis anlegen. Ich habe es unter /usr/portage/local/ gelegt, da dort auch Layman seine Dateien ablegt. Empfohlen wird normal /usr/local/portage/ allerdings sollte das relativ egal sein.

Ich zeige das ganze mal am Beispiel von Eqonomize. Dazu schmeißen wir einfach das heruntergeladen Ebuild in den Unterordner app-office/eqonomize. Anschließend noch kurz ein ebuild app-office/eqonomize/eqonomize-0.5.ebuild digest. Dies erstellt ein Manifest was einfach einige Checksummen zur Überprüfung enthält. Jetzt muss nur noch das Lokale Overlay in Portage bekannt gemacht werden. Das geschieht einfach über die Variable PORTDIR_OVERLAY="/usr/portage/local/local-overlay" die wir in der Datei /etc/make.conf hinzufügen müssen. Das einzige was noch fehlt ist das synchronisieren des Portage. Ich nutze dazu eix-sync da mir einfach die Ausgaben besser gefallen. Mit emerge geht's natürlich genauso.

Soweit meine Kurzeinführung in Lokale Overlays. Jetzt aber zu dem eigentlichen Feature. Ich bin es Leid bei ntfs3g jedes mal locale=de_DE.utf8 mitzugeben damit Umlaute richtig dargestellt werden. Deshalb möchte ich es gerne automatisch einfügen wenn ich mount.ntfs aufrufe. Das löse ich einfach über ein Patch im Lokalen Overlay. Ob dieses Beispiel jetzt sinnvoll bzw. der Aufwand gerechtfertigt ist sei mal dahin gestellt.

Dazu erst einmal ein Verzeichnis erstellen und die Aktuelle ntfs3g Version aus dem Portage kopieren. Der Unterordner files lege ich schon mal für den Patch später an.

mkdir -p /usr/portage/local/local-overlay/sys-fs/ntfs3g/files/

cp /usr/portage/sys-fs/ntfs3g/ntfs3g-1.1120.ebuild /usr/portage/local/local-overlay/sys-fs/ntfs3g/
cp /usr/portage/sys-fs/ntfs3g/metadata.xml /usr/portage/local/local-overlay/sys-fs/ntfs3g/

Anschließend die Datei /usr/portage/local/local-overlay/sys-fs/ntfs3g/ntfs3g-1.1120.ebuild Editieren und oben bei inherit multilib toolchain-funcs noch eutils hinzufügen. Außerdem weiter Unten noch folgenden Block, der das Auspacken und Patchen erledigt, einfügen:

src_unpack() {
      unpack ${A}
      cd "${S}"
      epatch "${FILESDIR}"/Makefile.am.patch
      epatch "${FILESDIR}"/Makefile.in.patch
}

Das war's so weit jetzt müssen wir noch die beiden gepatchen Makefiles erstellen. Dazu einfach das bestehende ebuild auspacken in /tmp/ verschieben und die beiden benötigten Dateien mit der Endung *.change kopieren

ebuild /usr/portage/local/local-overlay/sys-fs/ntfs3g/ntfs3g-1.1120.ebuild unpack

cp -r /var/tmp/portage/sys-fs/ntfs3g-1.1120/work/ntfs-3g-1.1120 /tmp/

cp /tmp/ntfs-3g-1.1120/src/Makefile.am /tmp/ntfs-3g-1.1120/src/Makefile.am.change
cp /tmp/ntfs-3g-1.1120/src/Makefile.in /tmp/ntfs-3g-1.1120/src/Makefile.in.change

Diese Dateien ändern wir nun. Als erstes Kommentieren wir die Zeile aus die den Link von ntfs-3g auf mount.ntfs-3g anlegt. Dann Fügen wir über echo Zwei Zeilen in die neue /sbin/mount.ntfs-3g Datei ein die ntfs-3g mit dem gewünschten Parameter aufrufen. Wer sich über die Maskierung wundert einfach mal ausführen und Anschauen. Ich hab ewig gebraucht bis ich das raus gefunden habe. Zu Letzt geben wir der Datei noch Ausführungsrechte und erstellen einen Link auf mount.ntfs. Das ganze muss in beiden Dateien (Makefile.in und Makefile.am) jeweils unter install-data-local: und install-exec-local: eingefügt werden. Die beiden Dateien sollen unter uninstall-local: auch wieder gelöscht werden.

-- vim -O /tmp/ntfs-3g-1.1120/src/Makefile.*.change
(install-data-local:|install-exec-local:)
#$(LN_S) -f $(bindir)/ntfs-3g $(DESTDIR)/sbin/mount.ntfs-3g
echo -e '#!/bin/bash\nntfs-3g "$$@" -o locale=de_DE.utf8' > $(DESTDIR)/sbin/mount.ntfs-3g
chmod +x $(DESTDIR)/sbin/mount.ntfs-3g
$(LN_S) -f $(DESTDIR)/sbin/mount.ntfs-3g $(DESTDIR)/sbin/mount.ntfs

uninstall-local:
$(RM) -f $(DESTDIR)/sbin/mount.ntfs
$(RM) -f $(DESTDIR)/sbin/mount.ntfs-3g
-- :wqa

Nun erstellen wir ein Patch zwischen der geänderten und der original Version. Das bash -c hilft mehrere Befehle auf einmal auszuführen. Das ist besonders hilfreich wenn man wie ich mit sudo arbeitet. Da man sonst evtl. keine Berechtigungen hat in die Datei zu schreiben. Die geänderten Dateien nun in unser lokales Overlay kopieren und wieder ein Manifest erstellen.

bash -c "cd /tmp/; diff -uN ntfs-3g-1.1120/src/Makefile.in ntfs-3g-1.1120/src/Makefile.in.change >  ntfs-3g-1.1120/src/Makefile.in.patch"
bash -c "cd /tmp/; diff -uN ntfs-3g-1.1120/src/Makefile.am ntfs-3g-1.1120/src/Makefile.am.change >  ntfs-3g-1.1120/src/Makefile.am.patch"

cp -v /tmp/ntfs-3g-1.1120/src/Makefile.*.patch /usr/portage/local/local-overlay/sys-fs/ntfs3g/files/

ebuild ntfs3g-1.1120.ebuild digest

Wer noch nicht die Variable für das lokale Overlay in die Datei /etc/make.conf eingefügt hat sollte das jetzt tun. Ansonsten wieder mit eix-sync synchronisieren. Hier sieht man dann das ein Update zwischen dem Originalen Portage und unserem Overlay statt gefunden hat. Installiert man nun wie gewohnt die Datei sieht man auch, dass das Portage gewechselt hat. Wenn man schnell genug ist, und ich die Ausgabe von emerge anschaut, sieht man sogar wie unsere beiden Patchs ausgeführt werden.

-- eix-sync
[ebuild   R   ] sys-fs/ntfs3g-1.1120  USE="-debug -suid" 0 kB [0=>1]
[0] /usr/portage
[1] /usr/portage/local/local-overlay
--

-- emerge -vat ntfs3g
[ebuild   R   ] sys-fs/ntfs3g-1.1120  USE="-debug -suid" 0 kB [1]

Total: 1 package (1 reinstall), Size of downloads: 0 kB
Portage tree and overlays:
 [0] /usr/portage
 [1] /usr/portage/local/local-overlay
--
--
>>> Unpacking ntfs-3g-1.1120.tgz to /var/tmp/portage/sys-fs/ntfs3g-1.1120/work
 * Applying Makefile.am.patch ...                                                                                                                                [ ok ]
 * Applying Makefile.in.patch ...                                                                                                                                [ ok ]
>>> Source unpacked.
--

So nun sollte alles Funktionieren. Man kann nochmal über eix nach unserem Paket suchen. So sieht dann dass die Version unseres Overlays installiert ist. Außerdem sollte man nochmal checken ob die Datei richtig erstellt worden ist und auch die Rechte und der Link so passen.

-- eix ntfs3g
[I] sys-fs/ntfs3g
     Available versions:  1.810 ~1.1030 ~1.1104 1.1120 1.1120[1] ~1.2129 ~1.2216 {debug suid}
     Installed versions:  1.1120(16:14:30 03/08/08)(-debug -suid)
     Homepage:            http://www.ntfs-3g.org
     Description:         Open source read-write NTFS driver that runs under FUSE

[1] /usr/portage/local/local-overlay
--

-- cat /sbin/mount.ntfs-3g
#!/bin/bash
ntfs-3g "$@" -o locale=de_DE.utf8
--

-- ls -l /sbin/mount.ntfs-3g
-rwxr-xr-x 1 root root 46  8. Mär 20:13 /sbin/mount.ntfs-3g
--

-- ls -l /sbin/mount.ntfs
lrwxrwxrwx 1 root root 19  8. Mär 20:13 /sbin/mount.ntfs -> /sbin/mount.ntfs-3g
--

Ich finde diese Möglichkeit absolut praktisch. Beachten sollte man allerdings, dass das lokale Overlay vor dem offiziellen Portage Vorrang hat, aber wenn jetzt z.B. die Version 1.2216 in unserem Portagetree stable wird dann hat diese vor dem lokalen Overlay Vorrang da sie aktueller ist. In diesem Sinne, fröhliches Merging!

1 Kommentar:

Aaron hat gesagt…

Danke für das Tutorial!
Irgend wie hab ich schon mal Lust mir Gentoo etwas näher anzuschauen, allerdings glaube ich das ich dann noch mehr am Rumspielen als am Arbeiten bin :)