Package source (pkgsrc)

pkgsrc heisst soviel wie „package(s) source“ und bezeichnet die native „Paket“-Infrastruktur unter NetBSD. Unter „Paketen“ werden hierbei die Software von Drittanbietern verstanden. pkgsrc selbst ist ähnlich portabel wie NetBSD und läuft unter mehr als einem Halben Dutzend Plattformen, u.a. *BSD, Solaris, Linux.

pkgsrc wird üblicherweise benutzt um Software von Drittanbietern zu kompilieren. Hierzu existiert ein ziemlich umfangreiches Verzeichnis von Software. pkgsrc selbst ist make basiert. Die wichtigen Voreinstellungen für pkgsrc werden in der Datei /etc/mk.conf vorgenommen (oder in $MAKECONF). Um pkgsrc zu nutzen wird ein BSD-kompatibles make(1) benötigt (d.h. GNU make tut's nicht). Unter NetBSD selbst ist das /usr/bin/make, unter „fremden“ Plattformen gibt es ein bmake im bootstrap-Kit.

Unter pkgsrc versteht man neben dem Verzeichnis an Makefiles aber auch die durch pkgsrc kompilierten Pakete. Diese enthalten Metadaten, wie bspw. die Abhängigkeiten von Software. Anstatt einfach „nur“ zu installieren, kann man mit pkgsrc auch binary packages erstellen – Pakete in binärer Form, welche einfach (und ohne Präsenz von pkgsrc und Kompilation) auf Maschinen installiert werden können.

pkgsrc branches

Grundsätzlich gibt es zwei Arten von pkgsrc: Den vierteljährlichen Zweig, sowie die aktuelle Entwicklungsumgebung. Um es in cvs(1) parlese zu sagen: die branches pkgsrc-YYYYQ[1234] und HEAD. Unter HEAD findet die Entwicklung statt, d.h. die pkgsrc Infrastruktur wird dort gepflegt aber auch die updates des Paketverzeichnisses findet unter HEAD statt.

Vierteljährlich wird HEAD dann einem bulk build unterzogen, Probleme werden lokalisiert und hoffentlich gelöst, das ganze findet dann auf einem branch wie bspw. pkgsrc-2009Q1 statt. Die Namensgebung „hängt hinterher“, d.h. bspw., daß pkgsrc-2008Q4 nicht nach 9 Monaten in 2008 rauskommt, sondern nach 12. Dieser branch wird insofern gepflegt, daß dort keine (großartigen) funktionalen Änderungen vorgenommen werden, sondern i.A. nur security fixes von Paketen eingepflegt werden. HEAD ist dagegen etwas vogelwild, aka „bleeding edge“. Dort bekomment man (zumeist) die neuesten Versionen von 3rdparty-software, auch die neuesten Pakete, aber dafür kann schon mal ein build fehlschlagen, oder was am Paket verquer sein.

Ein weiterer Vorteil der Q branches besteht in binary packages: Üblicherweise wird die software aus einem solchen branch in einem bulk build für das aktuelle NetBSD release und alle möglichen Architekturen übersetzt und auf ftp.netbsd.org zur Verfügung gestellt. D.h. indem man die PKGPATH Umgebungsvariable setzt, kann man mit pkg_add(1) ohne eigene Kompilation Pakete installieren oder updaten.

Ich (Fritz) empfehle daher, auf die Q branches zu setzen. Diese sollten natürlich auch regelmäßig updated werden.

Nutzung des Quellverzeichnisses

Prinzipiell ist das Erstellen/Installieren von Paketen mit pkgsrc ziemlich einfach:

cd Kategorie/Paket
make install clean-depends

Das war's schon.

Natürlich ist das aber noch nicht alles. Es gibt eine Vielzahl von verschiedenen make targets, die diverse Aktivitäten ausführen. Es gibt verschiedene Variablen, die den build beeinflussen. Es gibt (oft) verschiedene Optionen, die an- oder ausgeschaltet werden können.

Make targets

Hier eine Liste der verschiedenen make targets und was sie so bewerkstelligen:

fetch Lädt die Quellen für das Paket herunter
fetch-list Gibt ein shell-skript aus, welches die Quellen für dieses Paket und alle Abhängigkeiten herunterlädt. Nutzung üblicherweise mit make fetch-list | sh
checksum Überprüft die in pkgsrc gespeicherten Prüfsummen der heruntergeladenen Quellen
extract Extrahiert die Quellen
patch patcht die Quellen mit den fixes aus pkgsrc
tools Erstellt die lokale toolchain für das Übersetzen der Quellen
wrapper Packt die tools ein (gemäß all den gesetzten Variablen, CFLAGS etc.)
configure Konfiguriert die Quellen
build Übersetzt die Quellen
install = fetch, checksum, extract, patch, tools, wrapper, configure, build und installiert das Resultat der Übersetzung dann nach $PREFIX
package = install und packt danach das Paket zusammen. Zu finden unter $PKGSRCDIR/packages(/All)
clean Räumt auf
clean-depends Räumt aktuelles Paket und die benötigten Abhängigkeiten auf
update deinstalliert das Paket samt den von ihm abhängigen Paketen und übersetzt und installiert es, sowie die davon abhängigen Pakete neu
replace erstellt eine Sicherungskopie des aktuellen Paketes und ersetzt das Paket durch das neue Paket. Sollte nur benutzt werden, wenn man weiß, was man tut (und glaubt mir, ihr wisst es meistens nicht1))
show-installed-depends Zeigt die installierten Abhängigkeiten an
deinstall Deinstalliert ein Paket
show-var Zeigt den Wert der Variablen an, welche in der Variablen VARNAME übergeben wird. make show-var VARNAME=PREFIX
show-license Gibt die vom Paket verwendete Lizenz aus. make show-license | less
help Gibt Informationen zum Thema in der Variable topic aus. make help topic=help

Variablen

Variablen können, wie bei make üblich, als auf der Kommandozeile gesetzen Optionen übergeben werden, oder über Umgebungsvariablen eingestellt werden:

make VARNAME=WERT <target>
env VARNAME=WERT make <target>
VARNAME=WERT; export VARNAME
make <target>

Weiterhin können die Variablen auch in der Datei $MAKECONF, üblicherweise /etc/mk.conf gesetzt werden. Hier mal eine Liste der wichtigsten Variablen, und was man mit ihnen so alles anstellen kann2):

LOCALBASE Voreinstellung: /usr/pkg - dort werden die Pakete hininstalliert.
X11BASE Voreinstellung: /usr/X11R6 - dort wird nach X11 gesucht (falls es im Basissystem installiert wurde). Die X11 Pakete landen hier auch (ausser bei Nutzung von x11/xpkgwedge).
DISTDIR Voreinstellung: /usr/pkgsrc/distfiles - hier werden die runtergeladenen Originalquellen der Pakete hinterlegt.
PKG_DBDIR Voreinstellung: ${VARBASE}/db/pkg - hier wird die Datenbank der installierten Pakete, der zugehörigen Dateien etc. angelegt.
ACCEPTABLE_LICENSES Voreinstellung: “fee-based-commercial-use no-commercial-use no-profit limited-redistribution“ - Durch Leerzeichen getrennte Liste von „akzeptablen“ Lizenzen. Open-source oder freie Lizenzen sind per default akzeptabel.
PACKAGES Voreinstellung: ${PKGSRCDIR}/packages - Verzeichnis unter dem die Verzeichnishierarchie zum Speichern von erstellten binären Paketen angelegt wird (und die Pakete dann auch gespeichert werden).
WRKOBJDIR Voreinstellung: <leer> - Falls gesetzt werden unter diesem Pfad die „work“ Verzeichnisse angelegt, in denen die eigentliche Kompilation stattfindet, ansonsten werden diese Verzeichnisse direkt als Unterverzeichnisse in pkgsrc angelegt. Besonders sinnvoll, wenn ${PKGSRCDIR} auf einem read-only mountpoint liegt und/oder im Netzwerk.
DEPENDS_TARGET Voreinstellung: install - bestimmt wie Abhängigkeiten übersetzt werden. Interessante Alternativen: “install (dist)clean“, “package (dist)clean“.
PKGSRC_COMPILER Voreinstellung: gcc - compiler für die Kompilation von pkgsrc Paketen. Unterstützte Möglichkeiten umfassen unter anderem gcc, distcc, ccache.
CFLAGS Voreinstellung: <leer> - Zusätzliche Compilerflags für die Übersetzung von C Quellen. Sinnige Erweiterung, falls RAM genug ist, “-pipe“. CXXFLAGS adäquat für die Übersetzung von C++ Quellen.
LDFLAGS Voreinstellung: <leer> - Zusätzliche Linkerflags für das linken von Objektdateien.
ALLOW_VULNERABLE_PACKAGES Voreinstellung: <nicht gesetzt> - Wenn definiert, erlaube auch Pakete, die laut audit-packages verwundbar sind, ansonsten gibt's ne Fehlermeldung. Zu weiteren Details (wie man bspw. nur gewisse verwundbare Pakete erlauben kann), siehe man audit-packages.
MAKE_JOBS Voreinstellung: <nicht gesetzt> - Wenn gesetzt, bestimmt die maximale Anzahl an parallelen Prozessen zur Übersetzung von Quellen. Sinnvolle Werte sind <Anzahl der CPUs> - <Anzahl der CPUs * 2+1>. Manche Pakete spacken dann aber rum. Kann mit MAKE_JOBS_SAFE=no für einzelne Pakete ausgeschaltet werden.
OBJHOSTNAME Voreinstellung: <nicht gesetzt> - Wenn gesetzt werden die pkgsrc work Verzeichnisse mit .<hostname> erweitert. Sinnig, wenn pkgsrc über mehrere Kisten geteilt genutzt wird, und die mk.confs unterschiedlich sind bzw. unterschiedliche Architekturen am Start sind (aber siehe auch OBJMACHINE, welches Priorität über OBJHOSTNAME hat).
OBJMACHINE Voreinstellung: <nicht gesetzt> - Wenn gesetzt werden die pkgsrc work Verzeichnisse mit <.$(uname -m)> erweitert. Siehe oben.
PKG_SUFX Voreinstellung: <.tgz> - Wählt aus, ob binäre Pakete mit gzip (“.tgz“) oder bzip2 (“.tbz“) komprimiert werden.
PKGSRC_MESSAGE_RECIPIENTS Voreinstellung: <leer> - falls gesetzt, bezeichent eine Liste von usern, denen die MESSAGE Dateien von installierten Paketen zugemailt werden. Diese MESSAGE Dateien beinhalten üblicherweise Anweisungen, was noch zu tun ist, bevor das Paket (sinnvoll) genutzt werden kann, bzw. Warnungen etc.
PKGSRC_RUN_TEST Voreinstellung: <no> - wenn auf „yes“ gesetzt werden vor Installation der Pakete die testsuites der Pakete ausgeführt.
PREFER_NATIVE Voreinstellung: <leer> - Manche Pakete sind auch im Basissystem installiert. Wenn auf „yes“ gesetzt, werden alle möglichen Pakete aus dem Basissystem herangezogen. Ansonsten kann es auf eine Liste von Paketen gesetzt werden, die aus dem Basissystem genutzt werden sollen.
PREFER_PKGSRC Voreinstellung: <leer> - Manche Pakete sind auch im Basissystem installiert. Wenn auf „yes“ gesetzt, werden alle möglichen Pakete aus pkgsrc herangezogen. Ansonsten kann es auf eine Liste von Paketen gesetzt werden, die aus pkgsrc gebaut werden sollen. Interessantes Beispiel: openssl.
X11_TYPE Voreinstellung: <native> - bestimmt, welches X11-System zum Übersetzen und Linken von X-Paketen genutzt wird. Bei der Voreinstellung wird das X aus dem Basissystem genutzt. Bei “modular“ wird X.org aus pkgsrc genutzt.
FETCH_USING Voreinstellung: <ftp> - Bezeichnet das System, welches zum Saugen der Originalquellen benutzt wird. Mögliche Werte: manual, curl, custom, fetch, ftp, wget. Bei “custom“ müssen die weiteren FETCH_ Variablen gesetzt werden, ansonsten kann man, so man denn will, deren Argumente erweitern.
FETCH_CMD Voreinstellung: <hängt von FETCH_USING ab> - wird eigentlich nur bei FETCH_USING=custom benötigt.
FETCH_BEFORE_ARGS Voreinstellung: <hängt von FETCH_USING ab> - wird eigentlich nur bei FETCH_USING=custom benötigt. Ansonsten kann man, wenn ftp genutzt wird, diese Variable noch um “ -4“ erweitern (FETCH_BEFORE_ARGS+=“ -4“), um IPv4 Transport zu forcieren – IPv6 existiert ja nur in hubertf's Kopf bzw. nicht in der realen Welt…
FETCH_AFTER_ARGS Voreinstellung: <hängt von FETCH_USING ab> - wird eigentlich nur bei FETCH_USING=custom benötigt.
FETCH_RESUME_ARGS Voreinstellung: <hängt von FETCH_USING ab> - wird eigentlich nur bei FETCH_USING=custom benötigt.
FETCH_OUTPUT_ARGS Voreinstellung: <hängt von FETCH_USING ab> - wird eigentlich nur bei FETCH_USING=custom benötigt.
PKG_RESUME_TRANSFERS Voreinstellung: <no> - Falls ein fetch mittendrin fehlschlägt und die Variable auf „yes“ steht, wird beim nächsten mirror da weitergemacht wo der Transfer abriss, ansonsten wird das DISTFILE entfernt und von vorne angefangen.
PASSIVE_FETCH Voreinstellung: <undefiniert> - Falls definiert wird beim ftp-fetchen passive mode benutzt.
MASTER_SORT Voreinstellung: <.ac.at .at .de .ch .se .fi .no> - Durch Leerzeichen getrennte Liste von präferierten download-locations. Eventuell sinnig, hier “.de“ ganz nach vorne zu stellen.
PAPERSIZE Voreinstellung: <A4> - für Druck/Graphikpakete, Default Papiergröße. Alternative: letter.

Optionen

FIXME

/etc/mk.conf

FIXME

Nutzung der binären Pakete / pkg_* tools

FIXME

pkg_add

FIXME

pkg_admin

FIXME

pkg_create

FIXME

pkg_delete

FIXME

pkg_info

FIXME

pkgsrc up-to-date halten

Am einfachsten hält man pkgsrc mit cvs(1) up-to-date:

cd $PKGSRCDIR
# beim ersten Mal/wechseln eines Q branches
cvs -qz5 update -dPA -rpkgsrc-2009Q1 # bzw. entsprechender branch
# bei darauffolgenden Malen:
cvs -qz5 update -dP

Entsprechendes kann man natürlich auch in ein kleines shell-skript packen, unter /usr/local schmeissen und via cron(8) täglich/wöchentlich/sonstwielich ausführen (lassen). Auch via cron sollte man download-vulnerability-list ausführen lassen (aber siehe dazu auch weiter unten.

package tools -- nützliche pkgsrc-Pakete

devel/cpuflags

Besteht aus zwei Teilen: Einem shellskript, welches die für die aktuelle CPU/Architektur passenden -mcpu/-march Optionen für gcc(1) ausspuckt, und Makefilefragmenten, die in $MAKECONF (per default /etc/mk.conf) eingebunden werden können, um automatisch die passenden CPU Optimierungsflags für den Compiler zu setzen.

Ob sich das lohnt, müsste mal nachgemessen werden. Prinzipiell glaube ich (Fritz) daran, vor allem wenn SIMD Instruktionen dadurch aktiviert werden. Der Nachteil besteht darin, daß mindestens diese bzw. eine kompatible CPU mit dem buildhost benötigt wird, oder sonst kracht's auf anderen Maschinen.

Beispiel:

# minos
$ cpuflags
-mfpmath=sse -msse3 -march=nocona
# rfhinf038
-mfpmath=sse -msse2 -march=pentium4

Hier würde es beispielsweise krachen: rfhinf038 unterstützt nur SSE2 und ist „nur“ ein Pentium4. Pakete, die mit cpuflags auf minos gebaut würden, würden dann auf rfhinf038 höchst seltsam nicht funktionieren (nicht garantiert aber man wird garantiert drüber stolpern) 3)

Indem man folgendes zu seiner mk.conf hinzufügt, wird cpuflags nur genutzt, wenn die Variable USE_CPUFLAGS auf yes (Groß/Kleinschreibung egal) gesetzt ist:

...
.if defined(USE_CPUFLAGS) && !empty(USE_CPUFLAGS:M[Yy][Ee][Ss])
.sinclude "/usr/pkg/share/mk/cpuflags.mk"
.endif
...

Dann würde…

make package
env USE_CPUFLAGS= make package
env USE_CPUFLAGS=no make package
make USE_CPUFLAGS=guggenmermal package

…nicht optimiert übersetzen, aber folgendes schon:

env USE_CPUFLAGS=yes make package
make USE_CPUFLAGS=yes package
USE_CPUFLAGS=yes; export USE_CPUFLAGS 
# oder "export USE_CPUFLAGS=yes" für modernere Bourne shells als /bin/sh
make package

pkgtools/pkg_chk

pkg_chk ist ein shell skript, welches durch pkgsrc oder die Datenbank der installierten Pakete und verfügbaren binary packages wühlt. Es erfüllt drei wichtige Funktionen:

  • Überprüfen der Versionen der installierten vs. verfügbaren Quell- oder Binärpakete
  • Updaten der installierten Pakete
  • Installieren eines ganzen Sets von Paketen über eine Konfigurationsdatei.

Überprüfen installierter Pakete

Hierzu werden entweder verfügbare binäre Pakete oder pkgsrc selbst benutzt. Das Überprüfen ist eigentlich ein do-nothing Lauf durch die update-Logik, welches statt der Ausführung anzeigt, welche Pakete durch welche ersetzt würden. Hierzu müssen entweder unter dem Pfad $PACKAGES (Voreinstellung: $PKGSRCDIR/packages) binäre Pakete vorhanden sein, oder pkgsrc verfügbar. Wenn keine Optionen explizit angegeben werden, werden zuerst die binären Pakete, und bei deren Abwesenheit pkgsrc untersucht.

# Überprüfen der installierten Pakete
pkg_chk -uq
# Überprüfen der installierten Pakete vs. binäre Pakete
pkg_chk -uqb
# Überprüfen der installierten Pakete vs. pkgsrc
pkg_chk -uqs

Pakete updaten

Zuerst erstellt pkg_chk eine Liste der veralteten Pakete, deinstalliert dieses dann samt davon abhängenden Paketen und installiert dann die deinstallierten Pakete neu. Auch dies kann entweder mit binären Paketen geschehen, oder direkt von den Quellen aus. Hierzu gibt es zwei Strategien: Entweder auf pkg_chks Logik vertrauen, oder brutal alle veralteten Pakete deinstallieren und dann neu installieren. Letzteres war lange Zeit zu bevorzugen, da Pakete sonst teilweise mehrfach gebaut wurden (beim update aus den Quellen). Die aktuelle manpage dokumentiert dieses Fehlverhalten nicht mehr, daher gehe ich davon aus, dass diese auch nicht mehr existiert; meine Gewohnheit hat sich aber nicht geändert4)

# Variante 1: Vertraue dem Skript. Binäres update
pkg_chk -ub
# Selbiges von den Quellen aus. Mache auch bei Fehlern weiter
pkg_chk -usk
# Variante 2: Deinstallieren, installieren (lohnt, wenn überhaupt nur bei -s)
pkg_chk -g   # Liste installierter Pakete anlegen
pkg_chk -r   # veraltete Pakete deinstallieren
pkg_chk -ask # fehlende Pakete wieder hinzufügen. Mache auch bei Fehlern weiter.

Bulk-installationen

Hierzu erstellt man (händisch, oder auf einer Modellkiste mit pkg_chk -g) eine pkgchk.conf, und fügt die Pakete auf einer oder mehreren anderen Kisten dann mit pkg_chk -a hinzu. Lohnt besonders wenn man mehrere Kisten installiert und die gleiche Software auf allen zur Verfügung haben will. Interessant ist hier die Nutzung von tags, mit denen Software pakete gekennzeichnet werden können. Mit diesen Markern können Pakete nur für gewisse Verwendungszwecke gekennzeichnet werden, und falls diese Marker dann mit -D tag1,tag2,…,tagn gesetzt werden, werden die entsprechenden Pakete installiert. Zusätzlich zu diesen Markern können die tags auch anders genutzt werden:

  • - als tag: Paket wird nie installiert
  • kein tag: Paket wird immer installiert
  • * als tag: Hier wird jedes angegebene tag gematcht
  • /blabla: Paket wird installiert falls angegebener Pfad existiert und lesbar ist
  • tag1 tag2: „oder“ Verknüpfung von tags
  • tag1+tag2: „und“ Verknüpfung von tags

Welche tags werden per default installiert? pkg_chk -v fragen oder folgenden quote aus der pkg_chk manpage konsumieren: The default set of tags used to determine which packages to match in pkgchk.conf are equivalent to the output of the following with any spaces converted to hyphens (-): hostname -s, hostname, uname -srm, uname -sr, uname -sm, uname -s, uname -r, uname -m. If /usr/X11R6/lib/libX11.so or /usr/X11R6/lib/libX11.a is present, x11 is added to the list of tags.

In der manpage von pkg_chk ist ein Beispielfragment einer ausgefalleneren pkgchk.conf enthalten.

pkgtools/pkg_comp

Ein weiteres Beispiel, was mit ein bisschen shell-Skripterei und gutem Willen so alles erreicht werden kann. pkg_comp erstellt ein chroot, in welchem Pakete gebaut werden können, ohne den Betrieb des Systems außerhalb des chroots zu stören. Das ist gerade dann interessant, wenn neue (binäre) Pakete für ein update gebaut werden sollen.

Isoliert Pakete bauen

Warum? Man stelle sich vor, es gibt ein Paket X, welches man updaten möchte. Dieses Paket ist auf dem System installiert. Vom Paket X hängen die Pakete A, B und C ab. Gleichzeitig ist das Paket X vom Paket Y abhängig. Weiterhin gehe man davon aus, daß auch Y in einer neuen Version vorliegt, und daß X von der neuen Version von Y abhängt. Soll nun X in der neuen Version übersetzt werden, muß Y deinstalliert und auf den neuesten Stand wieder installiert werden (die Paketabhängigkeiten beziehen sich ja auf installierte Pakete). Wenn aber Y deinstalliert wird, wird auch X, und somit auch A, B und C deinstalliert.

Blöd, wenn die letzteren „wichtige“ benötigte Pakete sind!

Die Lösung: man schaffe sich eine „Spielumgebung“, die vom eigentlichen System abgeschottet ist (das chroot), und installiere dort die neue Version von Y und X (und, wenn man gleich mal dabei ist, auch A, B und C), erstelle für diese Pakete binäre Pakete. Dann kann man im eigentlichen System die Pakete mit minimalem Zeitaufwand updaten (wer nicht glaubt, daß das einen Unterschied macht, soll einfach mal folgende „Variablen“ einsetzen: Y = gtk2, X = firefox3, A = gnome, B = openoffice3, C = thunderbird. Selbst auf modernen Kisten sind das mehrere CPU Stunden!)

Pakete für andere NetBSD Versionen übersetzen

Das chroot muss ja irgendwo herkommen. Zu dessen Erstellung werden die NetBSD release sets benutzt, und da kann man ja auch eine andere Version installieren, als auf dem eigentlichen System installiert ist. Wenn man noch das Paket libkver benutzt, kann man so eine andere Kernelversion faken. Das mag beispielsweise dafür interessant sein, auf einem -current System Pakete für NetBSD 5.0 zu bauen, auf einem 5.0 für 4.0, oder auf einem 4.0 für 5.0.

Nutzung

pkg_comp nutzt man üblicherweise in ca. drei Schritten:

  1. chroot erstellen – pkg_comp makeroot
  2. Pakete bauen – pkg_comp build <Liste der Paketpfade (cat1/pkg1 cat2/pkg2 …)>
  3. chroot abreissen – pkg_comp removeroot

Per Voreinstellung werden im build Schritt binäre Pakete gebaut, die danach unter $PKGSRCDIR/packages zu finden sind.

Konfiguration

Der halbwegs knifflige Teil ist, pkg_comp richtig zu konfigurieren. Das macht man am besten, indem man sich erst einmal ein Fragment einer Konfiguration erstellen läßt, mittels pkg_comp maketemplate, welches eine Konfiguration ${HOME}/pkg_comp/default.conf erstellt (man ahnt es schon, man kann verschiedene Konfigurationsdateien bei pkg_comp auswählen). Diese Datei sollte man sich mal genau anschauen…

Wie sie schon besagt, sollte man auf jeden Fall einen Blick in man 8 pkg_comp werfen. Die Variablen, die man üblicherweise verändern will:

  • DESTDIR: Hierunter wird das chroot erstellt. Dicke Platz lassen! (der ist unter /var aber oft knapp)
  • DISTRIBDIR: Hierunter sollten die sets liegen, im Unterverzeichnis $(uname -m)/binary/sets
  • NETBSD_RELEASE: wenn nicht „no“, dann die NetBSD Version, als die man sich verkleiden will (vgl. uname -r)
  • SETS_X11: auf „no“ setzen, wenn X.org aus pkgsrc verwendet werden soll
  • PKG_DEVELOPER: sollte man nach Erstellung des chroots im dort generierten etc/mk.conf löschen (meiner Meinung nach: Verbraucht sehr viel CPU Zeit, erhöht den spam, ist nur für Hacker hilfreich)
  • EXTRAMK: Die Datei, auf die diese Variable zeigt, wird im .ifdef BSD_PKG_MK Block in die etc/mk.conf eingefügt. D.h. diese ist ein Fragment einer /etc/mk.conf – vor allem ohne das .ifdef BSD_PKG_MK (d.h. man soll nicht auf die globale /etc/mk.conf verweisen)! Dort können weitere Variablen gesetzt werden, wie beispielsweise akzeptierte Lizenzen, Paketoptionen etc. Um einen Geschmack zu geben, hier meine persönliche ${HOME}/pkg_comp/chroot-mk.conf (auf die EXTRAMK bei mir verweist):
##
## NOTIZ:
##
## PKG_DEVELOPER UEBER MIR AUSKOMMENTIEREN!
##
##

# 
.sinclude "/usr/pkg/share/mk/cpuflags.mk"

X11_TYPE=modular
# IpV6 ist Schaeuble'sche Netzwerktechnik!
USE_INET6=no
PKG_DEFAULT_OPTIONS+=-inet6
# gnupg mit IDEA wegen meiner archivierten Emails...
PKG_OPTIONS.gnupg+=idea
# gimp stuff... Gnome ist fuer loser!
PKG_OPTIONS.gimp=-gnome
# ruby mit RI!
PKG_OPTIONS.ruby=ruby-build-ri-db
# Gecko wird "offiziell"
PKG_OPTIONS.gecko=official-mozilla-branding -mozilla-jemalloc
PKG_OPTIONS.openvpnc=openssl
PKG_OPTIONS.modular-xorg-server=dri

# jaja.. NICHT UNBEDINGT EMPFEHLENSWERT!
ALLOW_VULNERABLE_PACKAGES=yes

#
MAKE_JOBS=2
COPTS?= -pipe ${DEFCOPTS}
CFLAGS+=-pipe
ACCEPTABLE_LICENSES+=adobe-acrobat-license  dbz-ttf-license eclipse-license \
 fee-based-commercial-use flash-license glimpse-license \
 graphviz-license hptools-license idea-license inlineegg-license \
 jdk-license kermit-license lame-license lha-license mame-license \
 mozilla-trademark-license mpg123-license mplayer-codec-license \
 ms-ttf-license no-commercial-use  no-redistribution openmotif-license \
 opera-license palmos-sdk-license pine-license pvs-license quakedata-license \
 rar-license sendmail-license shareware  sun-jdk6-license sun-jrl-16-license \
 sun-jsdk20-license  szip-license unarj-license unrar-license vim-license \
 xv-license zoo-license

Wie auch im Fragment zu lesen: Die Geschichte mit ALLOW_VULNERABLE_PACKAGES ist nicht unbedingt nachahmenswert, ich habe es aber gesetzt weil ich damit meine Kiste wie weiter unten beschrieben update. Und ja, ich hab auch ein paar verwundbare Pakete, die ich trotzdem gern auf dem neuesten Stand hätte. Auch die Geschichte mit IPv6 ist etwas Fritz-paranoid, warum ich das mache liegt aber außerhalb dieses howtos.

Wegen sonstiger Variablen vergleiche auch den Abschnitt selbigen Namens weiter oben. Die PKG_OPTION.modular-xorg-server=dri aktiviert die Direct Rendering Infrastructure, die auch im Kernel aktiviert sein muß (für bessere 3D Performance). Wegen sonstiger Optionen vergleiche auch den Abschnitt selbigen Namens weiter oben.

Dies soll nur als ein Beispiel dienen. Ein guter Anfangspunkt ist die eigene /etc/mk.conf, vor allem was gesetzte Paketoptionen betrifft.

Ach ja ...

pkg_comp muß man teilweise, und sollte es auch ansonsten als root ausführen! Und insbesondere die manpage sollte man sich wegen den möglichen Werten der Variablen in der Konfigurationsdatei und deren Auswirkungen ansehen.

pkgtools/pkg_rolling-replace

pkg_rolling-replace tut nun das, was man eigentlich tun sollte: Hirn nutzen. Auch dieses ist nichts weiter als ein „einfaches“ shell-skript, ähnlich wie pkg_chk kann es benutzt werden, um einen ganzen Packen Pakete auf einmal zu erneuern. Im Gegensatz zu (zumindest älteren Versionen von) pkg_chk nutzt es jedoch ein bisschen Hirn, oder genauer gesagt tsort(1) um eine topologische Sortierung des Abhängigkeitsgraphens der Pakete zu erstellen, und so eine „ideale“ Reihenfolge des Übersetzens der Pakete zu erreichen. Einerseits kann man mit pkg_admin Pakete markieren, die man gerne ersetzt haben möchte (beispielsweise, weil man deren Paket-optionen verändert hat), oder man kann pkg_rolling-replace auch anweisen, selbst herauszufinden, welche Pakete veraltet sind. pkg_rolling-replace erstellt auch binäre Pakete zur weiteren Verwendung beim Übersetzungsprozess.

Besonderheit

Die namensgebende Besonderheit ist, neben der Nutzung von tsort(1), daß pkg_rolling-replace make replace statt make update benutzt. Hierbei wird das installierte Paket zuersteinmal via pkg_tarup gesichert, das Paket neu übersetzt, und „unter den Füßen“ der Abhängigkeiten ausgetauscht. Das ist nicht unbedingt sicher… (wenn sich die API oder ABI verändert hat/haben) …daher wird auch in pkgsrc davor gewarnt (damit man nachhert bei Problemen „You have been warned!“ sagen kann). Normalerweise geht es gut, zumeist bei Paketen aus der BSD Welt. Bei „dicken“ GNU Libs kracht es leider öfter5). Wer hier sichergehen will, sollte die -s flag von pkg_rolling-replace nutzen.

Die weitere Auswirkung der Nutzung von make replace ist, daß das Paket „mal eben nur kurz“ nicht zur Verfügung steht. Selbiges gilt für die Abhängigkeiten. So kann man mal „eben schnell“ gtk ersetzen ohne gleich ein komplettes neues GNOME, GIMP, firefox et al bauen zu müssen.

Nutzung

pkg_rolling-replace [-r] [-s] [-u] [-X/-x pkgs]

[pkgs] ist hierbei eine durch Kommata getrennte Liste von Paketpfaden (bspw. x11/rxvt) im Falle von -x oder eine Liste von Paketnamen (bspw. rxvt) im Falle von -X. -r verhindert die Erstellen von binären Paketen. -s aktiviert den „strict“ mode, in dem auch bei „nur potentiellen“ ABI Änderungen die abhängigen Pakete neu gebaut werden, meiner Meinung nach sollte das von keinem pkg_rolling-replace Aufruf weggelassen werden. -u letztlich nutzt pkg_chk(8), um erstmal festzustellen, welche Pakete veraltet sind, und baut diese dann neu.

Übliche Nutzungen zum globalen Systemupdate sie auch weiter unten.

Eine weitere Nutzungsmöglichkeit ist, via pkg_admin set rebuild=YES <paket> pkg_rolling-replace zu signalisieren, welche(s) Paket(e) neu erstellt und installiert werden sollen. Das kann optional zusätzlich zu -u geschehen. Wie schon geschrieben, ich persönlich würde immer -s dazu nutzen.

Anmerkung

Ich nutze es nicht mehr. Ich hatte mal ein Problem damit, habe eine andere Strategie entwickelt und bin mit der zufrieden. Never change a running procedure! Andererseits muß ich auch eingestehen, ich weiß gar nicht mehr, was das Problem war. Seitdem ist auch viel Wasser die Donau, den Regen und den Potomac heruntergerauscht. Und pkg_rolling-replace wurde erheblich weiterentwickelt. Ich mache auch nur noch globale updates auf einen Rutsch, daher brauche ich das Skript eigentlich gar nicht. Wer's ausprobiert, kann zur Sicherheit via pkg_tarup eine Sicherungskopie der installierten Pakete erstellen und es dann mal ausprobieren. Ich bitte darum, negative wie auch positive Erkenntnisse hier zu notieren.

pkgtools/pkg_select

pkg_select ist mit dem Hintergrund entstanden, daß manche (ziemlich stur, laut und uneinsichtig) behaupten, es sei einfacher sich durch 20 Menüs durchzuhangeln, als durch das Dateisystem, und sich dabei drei essentielle make targets merkend. Und so kam, was kommen musste, ein curses basierendes frontend für pkgsrc und die base package tools wurde geschrieben.

Ich habe es selbst noch nicht benutzt, hubertf aber offenbar, und es scheint offenbar auch nicht so schlecht zu sein. Wer sich also dediziert lernresistent zeigen will, sollte es mal damit versuchen. Natürlich hat man hier ein Henne - Ei - Problem – wie bekomme ich pkg_select ohne die Installation von pkg_select installiert? Naja. Nicht mit pkg_select.

Hier ist der Anspruch und Funktionsumfang von pkg_select zitiert:

$ cat /usr/pkgsrc/pkgtools/pkg_select/DESCR
pkg_select will display a curses file browser for the pkg system. You can
browse pkgsrc and gather various informations about packages, like avail-
able version, installed version, comment and homepage. A simple paging
system lets you read information files.  You can browse both installed
and uninstalled packages, as well as dependencies list and perform vari-
ous administrative tasks to them. A package finder system helps you to
easily locate a package by its name.  pkg_select can handle either source
or binary installations when pkgsrc is installed on the local system, or
binary only when using the pkgsrc-over-ftp feature.

If no pkgsrc is installed, pkg_select offers ability fo fetch it, either
by FTP or CVS. It is also possible to update an existing pkgsrc via the
interface.

pkg_select user interface is quite self explainatory, every available
shortcut is shown and annotated.

Wer Erfahrungen damit sammelt soll sie bitte hier dokumentieren. Danke.

pkgtools/pkg_tarup

Tödlich praktisches Skript, welches aus einem bereites installiertem Paket ein binary package erstellt. Sehr praktisch um vor Installation einer neuen Version ein backup zu machen, oder um mal schnell ein (paar) Paket(e) auf Kiste 1 zusammenzupacken und auf Kiste 2 zu installieren. Wird auch von make replace benötigt.

pkg_tarup [-a] [-d <verzeichnis>] <name-oder-pattern>

Wird -a mit angegeben, werden Abhängigkeiten auch verpackt. Voreinstellung für die -d Option, welche bestimmt wo die Pakete nachhert landen, ist /tmp (Da kann aber schnell mal der Platz knapp werden).

Bei <name-oder-pattern> handelt es sich um dasselbe, was auch pkg_info als Argument akzeptiert. Beispiele:

# brauch mal schnell firefox anderswo:
pkg_tarup -a -d . firefox3
# Komplett Paket backup
pkg_tarup -d pkg-backup \*

Pakete up-to-date halten

pkg_chk

pkg_chk ist eigentlich nichts mehr als ein „kleines“ shell skript, welches die diversen pkg_XXX tools aufruft bzw. make(1) nutzt um durch pkgsrc zu wühlen (letzteres muß also beim Nutzen der „from source“ Option -s vorhanden sein) und dann viele make updates aufruft (oder pkg_deletes gefolgt von pkg_adds). Hilfreich, hat aber auch Kanten – vor allem will man sicher nicht, daß pkg_chk mittendrin aufhört, bspw. wenn es über einen Fehler beim Bauen eines Pakets stolpert. Dazu dient die -k Option (continue on error).

Aus pkgsrc selbst

pkg_chk -usk

Alternativ:

pkg_chk -g
pkg_chk -r
pkg_chk -ask

Erklärung warum die Alternative siehe weiter oben.

Mit binary packages

pkg_chk -ubk

generell

Zur Sicherheit mit

pkg_chk -C <pfad> -g

eine pkgchk.conf erstellen und nach dem update mit

pkg_chk -C <pfad> -uaqn

den Erfolg überprüfen.

pkg_rolling-replace

  • Sicherstellen, dass pkg_chk installiert ist.
  • Alle veralteten Pakete und deren Abhängigkeiten neu bauen und installieren:
    pkg_rolling-replace -ur
  • Zusätzlich binäre Pakete erstellen:
    pkg_rolling-replace -u
  • Zusätzlich sicherstellen, dass Änderungen in der ABI6) übernommen werden:
    pkg_rolling-replace -us

Empfehlung

Die folgende Strategie nutze ich (Fritz) persönlich, um die Pakete auf von mir verwalteten Maschinen auf den neuesten Stand zu bringen:

# 1) Erstelle pkg_chk kompatible Liste der Pakete, aber so sortiert,
# dass die Abhaengigkeiten zuerst kommen.
pkg_info -a -Q PKGPATH > /tmp/packages.conf
#
# 2) erstelle chroot zum Pakete bauen
pkg_comp makeroot # siehe auch oben
#
# 3) baue binary packages fuer alle momentan installierten Pakete
pkg_comp build $(cat /tmp/packages.conf) 2>&1 | tee -a /tmp/pkg_comp.$(date +%F)
#
# (/tmp/pkg_comp.$(date +%F) kontrollieren)
# Folgendes überprüfen (sollte nichts ausspucken):
# pkg_chk -buqn 2> /dev/null | grep -v 'binary package available' 
# 
# 4) Pakete mit binary packages updaten
pkg_chk -bu
# pkg_chk -C /tmp/packages.conf -aqn # überprüfen (sollte nichts ausspucken)
#
# 5) Aufraeumen
pkg_comp removeroot
# Fertig

Der Nachteil der Strategie (gegenüber updaten mit pkg_rolling_replace ist, daß durch pkg_comp temporär ein erheblicher Platzbedarf besteht (mehrere Gigabyte). Die Vorteile überwiegen jedoch meiner Meinung nach:

  1. Nach dem update stehen die binary packages noch zur Verfügung. Diese können auch für andere Maschinen genutzt werden.
  2. Bis zu Schritt 4) sind alle Pakete weiterhin auf der Kiste installiert. Nur während dieses Schritts werden Pakete deinstalliert, d.h. die Zeit, während software auf der Maschine fehlt wird minimiert.
  3. Durch das Bauen der Pakete „vorher“ sitzt man nicht mit ner halbinstallierten Kiste da, sollte irgendetwas schief gehen.

pkgsrc & Sicherheit

audit-packages

…sollte via cron oder /etc/security.local automatisch regelmäßig ausgeführt werden.

Zur Nutzung via cron einfach der root-crontab einen entsprechenden Eintrag hinzufügen, für /etc/security.local einfach einen Aufruf in selbige Datei schreiben (für Beispiele zu beidem siehe pkg_info -D pkg_install).

Eigentlich besteht audit-packages aus zwei Teilen, download-vulnerability-list, welches vom NetBSD FTP Server die vom pkgsrc-Team gepflegte Liste der Softwarekrankheiten runterlädt (optional dessen Signatur überprüft etc. etc.) und wie audit-packages regelmäßig ausgeführt werden sollte, und eben aus audit-packages, welches die Liste der installierten Pakete gegenüber der Datenbank der bekannten Sicherheitsprobleme/-lücken der installierten Pakete überprüft. Es steht nicht immer ein Fix für ein erkanntes Problem bereit – aber das Bewußtsein für die vorhandenen Probleme wird geschärft. Beispiel einer Ausgabe (Zeilenumbrüche vor „see“ von mir):

$ audit-packages
Package mutt-1.4.2.3nb2 has a signature-spoofing vulnerability, 
  see: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1268
Package xerces-c-2.7.0nb2 has a denial-of-service vulnerability, 
  see: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-4482
Package links-gui-2.2nb1 has a remote-spoofing vulnerability, 
  see: http://secunia.com/advisories/33391/
Package libmikmod-3.1.11.1nb3 has a remote-denial-of-service vulnerability, 
  see: http://secunia.com/advisories/33485/
Package cups-1.3.9nb2 has a multiple-vulnerabilities vulnerability, 
  see: http://secunia.com/advisories/34481/
Package cscope-15.6nb2 has a remote-system-access vulnerability, 
  see: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0148

audit-packages kann man auch anweisen, nur gewisse Arten von Sicherheitsproblemen anzuzeigen, hierzu kann man die -t Option benutzen.

$ audit-packages -t remote-system-access
Package cscope-15.6nb2 has a remote-system-access vulnerability, 
  see: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0148

Für weitere Informationen lesen Sie die Packungsbeilage7) oder konsultieren Sie bitte Ihren Arzt8) oder Apotheker9)!

Externe Resourcen

Die wohl wichtigste: Der pkgsrc guide, auch verfügbar unter pkgsrc selbst, unter $PKGSRCDIR/doc/pkgsrc.html oder $PKGSRCDIR/doc/pkgsrc.txt. Ansonsten lohnt es sich auch mal einen Blick unter $PKGSRCDIR/doc zu werfen. Pkgsrc hat eine Homepage unter http://www.pkgsrc.org.

1) Wenn ihr euch sicher seid, dass enthaltene shared libraries keine Änderungen in der API/ABI beinhalten, das interface der enthaltenen Programme gleich geblieben ist und auch sonst für die abhängigen Pakete keine Änderungen zu erwarten sind, dann geht es, meistens. Wenn keine davon abhängigen Pakete installiert sind, kann man genausogut make update benutzen. Ansonsten gilt: You have been warned!
2) Weitere Informationen findet man auch unter ${PKGSRCDIR}/mk/defaults/mk.conf und mit make help topic=<VARNAME>
3) Anmerkung: minos ist natürlich ein amd64 (hallo felix!), weswegen auf minos gebaute Pakete eh auf anderen Kisten unbrauchbar sind
4) Eine historische Anmerkung dazu: Das ganze kam daher, dass die Liste der Pakete nicht so sortiert wurde, daß die Abhängigkeiten zuerst kommen. Ich habe dann einen patch entworfen, der pkg_chk um eine -o(rdered) Option erweitert, welche diese Sortierung vornimmt. Leider habe ich den patch nur an David Brownlee geschickt, und muß dort in einem spamfilter gelandet sein. Nach diversen Nöldurchgängen wurde das ganze inzwischen auch so implementiert (und als Alternative in pkg_rolling-replace). Was lernen wir daraus? Bei Verbesserungsvorschlägen entweder send-pr(1) nutzen oder mindestens eine Mailingliste als CC: nutzen um a) sanften öffentlichen Druck aufzubauen und b) die Mail Archive als Patch-backup zu mißbrauchen. Nachtrag hierzu: Ich habe es nicht geträumt. Ich wusste ich hatte irgendwas an die mailingliste geschickt. Es war halt kein patch sondern nur ein highlight, wie es getan werden könnte. die Nachricht im Archiv Patches braucht die Welt!!!
5) das ist jetzt mal keine „religiöse“ Werbung für BSD und ein dissen von GNU sondern leider meine leidvolle Erfahrung. Ich habe schon viele Diskussionen über ABI Änderungen auf BSD Mailinglisten mitbekommen, und wie pingelig und genau die Entwickler vorgehen. Ich habe auch schon Antworten auf crossposts mitbekommen wo gtk Entwickler fragten, Häh? Was isn ne ABI? Go figure.
6) Application Binary Interface, bspw. Größenänderungen in von shared libraries verwendeten Datentypen während die API gleichgeblieben ist
7) man audit-packages
8) Fritz
9) Felix
howto/netbsd/pkgsrc.txt · Zuletzt geändert: 2009/06/25 13:10 von Fritz
Nach oben

Anmelden





Login mit Zertifikat

Noch nicht registriert? Melde Dich jetzt als neuer User an
Passwort vergessen?

Server monitoring / website monitoring with Livewatch.de
Server Monitoring with Livewatch.de