Skip to content
Thomas Kreitler edited this page Sep 23, 2021 · 18 revisions

Neues Package für /pkg-Pfad:

  • We need a build script for the new package. The build-script should be self-contained. So it aside from running it as the build user to install the package into /pkg, it may also be run with you username to install the package to somewhere you may write to (e.g. /dev/shm or /scratch/local).

  • As a first step you might want to check if the package isn't already available.

  • So a suggested way to to develop the build script is, to do it under you username to a local installation directory first:

    • Clone git@github.molgen.mpg.de:mariux64/pkg-scripts.git (or pull latest changes)
    • Start with TEMPLATE.sh or the script of a previous version of your software or with a recent script.
    • Change the prefix to a writable local directory (/dev/shm , /scratzch/local) instead of /pkg
    • Develop your script until it is able to build the package for your username.
    • Change the prefix back to /pkg and follow the next sections:
  • Package reservieren:

    Als root@afk das neue Package in /project/config/src/mxpkg mit dem Keyword BUILD einbauen und verteilen:

    ssh afk
    cd /project/config/src
    
    sudo vi mxpkg
    sudo make
      -- or when you are root --
    vi mxpkg
    make
    

    Make verteilt die Datei auf alle Systeme nach /etc/mxpkg und triggert, dass alle Systeme ihre /pkg automount-map (/etc/automount/auto.pkg) daraus neu bauen. Normalerweise sind /pkg-Pfade read-only, aber durch das keyword BUILD werden die Pfade für Packages, die gerade gebaut werden, read-write gemountet.

  • Im eigenen clone von diesem Repository neues build-Script anlegen. z.B.:

    git pull
    cp example-1.0-0.build.sh example-1.1-0.build.sh
    vi example-1.1-0.build.sh    # update version-number
    git add example-1.1-0.build.sh
    git commit -m"Add example-1.1-0"
    
  • Optional als Normal-User testen (s.u.)

    Wichtig ist hier, das eigene *build.home.tmp Geraffel zu löschen, sonst geht man beim nächsten Schritt evtl. baden (permission denied).

  • Package bauen

    sudo tools/build.sh example-1.1-0
      -- or when you are root --
    tools/build.sh example-1.1-0
    

    Beim build werden sicher oft Fehler auftreten, was zu einem Abbruch des builds führen sollte. Man kann sich dem Iterativ nähern:

    vi example-1.1-0.build.sh     # fixe einen Fehler
    sudo tools/build.sh example-1.1-0
      -- or when you are root --
    tools/build.sh example-1.1-0
    

    bis es klappt. Da die späteren Aufrufe aber nicht mehr bei Null anfangen, sondern in einem Verzeichnis, in dem von den vorherigen Versuchen schon Dateien rumliegen (was gut ist, damit die Iteration oben schneller geht), sollte man zum Schluss sicherstellen, dass das Script nunmehr in der Lage ist, von Null zu bauen. Das build.sh script hat eine Option --purge um alle alten Relikt-Dateien (einschließlich der Downloads) zu löschen.

    Nach Fehlerkorrekturen also ganz zum Schluss

    sudo tools/build.sh example-1.1-0 --purge
      -- or when you are root --
    tools/build.sh example-1.1-0 --purge
    

    Und bitte auch alle Änderungen am build-Script committen:

    git add example-1.1-0.build.sh
    git commit -v
    git push
    
  • Package zumachen

    Als root@afk aus /project/config/src/mxpkg das Keyword BUILD bei dem Package entfernen

    ssh afk
    cd /project/config/src
    
    sudo vi mxpkg
    sudo make
      -- or when you are root --
    vi mxpkg
    make
    

Debug build problems

  • Einfach mal als build-user selber in den ausgepackten Sourcen rumediteiren und "make" uns sowas versuchen:
    sudo su - build
      -- or when you are root --
    su - build
    
    cd /package/pkg/example-.1.2.3-0
    # whatever... 
    

Ziele

  • Die Build-Scripte sollten auch als User ohne den tools/build.sh funktionieren (Wenn der prefix nicht auf /pkg/ sondern auf etwas zeigt, was der User beschreiben darf)

Tips

  • Make sure you have a clean environment when testing as normal user, stuff like LD_LIBRARY_PATH and home/bin in the PATH will produce funny errors if tools required for the build compete with your favorites.

  • During development you might want to have an explicit "exit 1" at the end of the script. It serves two purposes:

    • This way you can immediately see from looking at the build output or log, whether your build was terminated due to a failure somewhere (because of set -x) or whether it successfully ran to the end
    • The forced failure at the end prevents the tools/build from 'closing' your package by changing its owner to bin:bin.
  • During development you might want to set the PREFIX to something like "/dev/shm/$PKG-$VERSION-$BUILD" and run the script yourself (as ./PKG-VERSION-BUILD.build.sh 2>&1 | tee PKG-VERSION-BUILD.build.log) instead of using tools/build` and automount/nfs pkg paths.

  • During development you might want to skip parts of your build script which already done and go right to the trouble points. You can masks sections in

    if false; then #############################
    code to skip
    fi #########################################  
    
  • During development you might want to edit the script that just builds. Add the following line after the shebang

    COOKIE=$(mcookie); grep -v V_GREP_ME $0 > /dev/shm/runme-$COOKIE.sh ; sleep 1; exec bash /dev/shm/runme-$COOKIE.sh
    

    Bonus: you get also a temporary history of your script in /dev/shm :)

  • If you want to build "the real thing" in /dev/shm or another local path instead of nfs to speed up building:

    • Create a local directory: umask 022;sudo mkdir /dev/shm/PKG-VER-REV;sudo chown build:build /dev/shm/PKG-VER-REV
    • Force automount to mount the nfs directory: ls /pkg/PKG-VER-REV
    • Bind-mount the local directory over the nfs directory: sudo mount --bind /dev/shm/PKG-VER-REV /pkg/PKG-VER-REV
    • Prevent automount from unmounting the bind mount: (cd /pkg/PKG-VER-REV;sleep 1d) &
    • Now do your build...
    • Copy the package: sudo cp -a /dev/shm/PKG-VER-REV/* /package/pkg/PKG-VER-REV/.
    • Kill the lock: kill %1
    • Unmount the bind mount: sudo umount /pkg/PKG-VER-REV

Package wrapper

Das ist OUT-DATED! Hier geht's weiter: /usr/local/package

Mind the note: DO NOT EDIT outside of the mxtools repository

Die Wrapper (/usr/local/package/bin , /usr/local/package/lib) werden einfach auf dem distmaster erzeugt und gedistet. Profile-Files für Packages aus mxpkg werden automatisch in /usr/local/package/lib angelegt, die müssen also nicht von Hand angelegt werden. Den Config-File muss man nur editieren, um ggf. Aliase zu definieren (so dass z.B. prun example cmd identisch ist mit prun example-1.2.3-4 cmd) oder natürlich Programme aus dem Package, die im Pfad sein sollen (so dass z.B. cmd identisch ist mit prun example cmd

ssh deinemuddah
sudo -s
cd /usr/local/package/admin
vi config     # optional
./makebin

Package Wrapper: Package Aliases

Now a package can have an aliase name so that users can use prun with the alias package name instead of the real package name. So, for example, "perl" may be an alias package name to perl-5.24.1-0 or whatever is considered to be the default (latest and greatest) . An alias is declared in /usr/local/package/admin/config like this:

perl=perl-5.24.1-0

So people can use "prun perl CMD" and don't need to know the exact version of the default perl package.

Package Wrapper Command Aliases

Now a command declared in /usr/local/package/admin/config can be an alias to another command which is executed in a a package. So for example 'java7' can be declared to run the command "java" in the "jdk-7" package:

 jdk-7
    java7=java

Donalds "Überlegungen zu Packages"
  • Komplexe Software

    • kann aus dem einen oder anderen Grund nicht so einfach mit bee nach /usr/bin installiert werden.
      • viele optionale Module
      • eigenes Build-System oder eigene Modulverwaltung
      • Build-System lädt Sourcen oder Module aus dem Internet (nicht reproduzierbar)
      • wird potentiell in mehreren Versionen und/oder Varianten benötigt
      • viele viele GB und Files (?) - zB auch Zeit beim Installieren...
    • Beispiele: Sprachen/Libraries: perl,R,python2,python3,mathematica,node.js,Haskell,qt, ...
    • Beispiele: Anwendungen: inkscape, pandoc, rstudio,cytoscape, ...
  • Probleme bei NFS-Lösungen (/package/...)

    • Einige Software, die fast überall oder im Cluster läuft, ist remote und beschert uns so Netz-Anhängigkeiten, Geschwindigkeitsprobleme, Probleme bei Serverwartung wegen remote-mounts ( python, R, ... )
    • Einige Software wird vor Verfügbarkeit von Netz/nfs/automount benötigt (perl...)
  • Probleme bei lokalen Lösungen "im System" ( /usr/bin, /usr/local/bin ):

    • Nur eine Version möglich (perl)
    • keine langsame Transition oder Test mit alten Varianten möglich
  • Probleme bei allen lokalen Varianten (/usr/bin , /opt/VERSION, ...)

    • Platz ist limitiert ( system-python .vs. scientifiy python (*zig varianten) ) ?
  • Lösungsansatz:

    • komplexe Software wird in ein Directory gebaut und hat einen version und revison-tag ( zB. python-2.7.11-3 )
    • Paket kann entweder remote oder lokal sein
    • Kopien (Master, nfs-server, lokale Platte) per Definition identisch. Einmal eingerichtet ist Paket read-only. Bei Änderungen wird neue Revision gemacht
    • Am besten durch bin:bin owner (und read-only mount ?) forciert
      • NFS readonly: vermutlich nfs performance besser, aber Installation neuer packages/revisions deutlich komplexer
    • Die Auswahl, was lokal ist (und wo) soll nicht unbedingt auf allen Systemen gleich sein
    • Zumindest zur Build-Zeit sollten die Packages direkt dort gebaut werden, wo sie später laufen.
  • Randbemerkungen (warum andere Ideen nicht funktionierten)

    • nicht über Symlinks ( da Build-Systeme und auch Applikation den Zielpfad sehen und leaken)
    • Es wird (leider) in jedem Fall auch automount benötigt, da nicht alle Packages lokal sind und nfs-Mounts nur bei Bedarf gemacht werden sollen
    • Es soll auch kein Directory mit Symlinks zu automount-Pfaden geben (sonst ls -lL tödlich).
    • Direct maps würden automount und nicht-automount verzeichnisse im gleichen Directory ermöglichen. Knock-Out Nachteil: Jedes nicht-lokale Unterverzeichnis wäre ein ständiger autofs kernel mount
    • In autofs-Verzeichnissen manuell zu mounten, ist schwierig, da man darin keine eigenen Directories als mountpoint anlegen kann. Drübermounten geht zwar, aber dann ist der nfs-mount auch da und zudem verdeckt und wird vom automount dismountet.
    • Die "Weiche" lokal oder remote muss also über die automounter-Map erfolgen. Da das per Software-Package (R-3.2.1-0,R-3.2.1-1,...) geht, muss es eine neue Map sein (also nicht /package). Die Map ist nicht auf allen Systemen gleich, da cache unterschiedlich sein kann.
    • Nachteil: Wenn mal was gemountet ist, kann man nicht ändern/dismounten, so lange Prozesse finger drauf haben.
  • Lösungsvorschlag konkretes Beispiel:

    Map für "/pkg" mit autofs

/pkg autofs

R-3.2.1-0 -> server:/somewhere/pkg/R-3.2.1-0 (read-only, package kommt von remote) R-3.2.1-1 -> :/opt(?)/pkg/R-3.2.1-1 (read-only, package wird aus lokaler Kopie geladen) R-3.2.1-2 -> :/scratch/local/R-3.2.1-2 (read-write, nur zum Bauen neuer Revisionen)

Die Maps auf den Systemen können sich unterscheiden (zB. Abhängig von Bedarf oder Plattenplatz)

/opt/pkg/PKG-VER-REV ist lokaler Package (cache). Kann auch auf andere Partition symlinken

server:/somewhere/pkg/PKG-VER-REV ist read-only nfs export. Eventuell redundant, eventuell mit virtueller Adresse für failover möglich(?). server:/somewhere/pkg/PKG-VER-REV Das "somewhere" sollte nicht in bestehende /package zeigen weil

  • /package/whatever/.../PREFIX wäre direkter mountpoint. Wenn der Maintainer von /package/whatever an den Directories ändert, gibt es evtl. stale nfs handle
  • Undurchsichtig, weil aktuell Software in /package/whatever mit PREFIX auf /package/whatever gebaut wird, aber die neue Varianten sollten PREFIX /pkg/XXXX haben.
  • Das neue package-Repository sollte also besser nicht in bestehende /package verteilt werden, sondern eventuell an einer Stelle neu aufgebaut und eventuell repiliziert werden. Beispiel:

/project/packages/pkg

R-3.2.1-0.build.sh    # build script 
R-3.2.1-0.build.log   # build log 
R-3.2.1-0                 # PREFIX, exportiert. Darin Installation und build-Directory 

R-3.2.1-1.build.sh    # build script 
R-3.2.1-1.build.log   # build log 
R-3.2.1-1                 # PREFIX, exportiert. Darin Installation und build-Directory 

...

Aus der /pkg map wird dann aber direkt gemountet:

R-3.2.1-0 -ro SERVER:/amd/SERVER/X/Xnnnn/project/packages/pkg/R-3.2.1-0


Diskussion

Abgrenzung zu bee?

  • Alles lokal ?
  • repository ?

/scratch autfs pkg -> /amd/$host/P/pkg und symlink

/pkg autofs

R-3.2.1-0 -> afk:/amd/akf/1/package/pkg/R-3.2.1-1 (read-only, package kommt von remote)

R-3.2.1-1 -> :/amd/$host/P/pkg/R-3.2.1-1 (read-only, package wird aus lokaler Kopie geladen) R-3.2.1-2 -> afk:/amd/akf/1/package/pkg/R-3.2.1-2 (read-write, package wird remote gebaut)

R-3.2.1-3 -> /scratch/tmp/xxxx (read-write, package wird lokal gebaut)