#acl hayd@cbs.mpg.de:read,write,delete,revert,admin Known:read,write All:read = Definition File = Ein Defnition-File ist wie eine Bauanleitung zu verstehen für den [[https://wiki.init.mpg.de/IT4Science/SingularityContainerBauen|Bau eines Containers]]. Immer absolute Pfade angeben bzw. Umgebungsvariablen benutzen! <> == Was ist ein Definition File? == '''Es legt fest:''' * welches OS bzw. Container als Basis dient * welche Pakete installiert werden sollen * Umgebungsvariablen zur Laufzeit * benötigte Files vom Host * Metadaten und Beschreibung des Containers == Definition File eines Containers anzeigen == * wird beim Bau eines Singularity Containers in diesen gesichert * Unter {{{/.singularity.d/bootstrap_history}}} im Container sind alle bisher für den Container genutzten Definition Files hinterlegt. * So ist es möglich, sich das Definition File eines Containers anzeigen zu lassen: {{{ $ singularity inspect -d CONTAINER.sif }}} == Beispiel für ein komplettes Definition-File == Folgend ist ein komplettes Definition File aufgeführt. Die einzelnen Abschnitte werden in den folgenden Abschnitten erläutert. Würde man daraus einen Container bauen, so würde diesem ein Ubuntu 18.04 zugrunde liegen und eine netcat-Installation enthalten. Für die praktische Anwendung ist dieser eher ungeeignet, da das Definition File nur zur Veranschaulichung zusammengestellt wurde. Praktikablere Beispiele sind im letzten Abschnitt zu finden. {{{ Bootstrap: library From: ubuntu:18.04 %setup touch /file1 touch${SINGULARITY_ROOTFS}/file2 %files /file1 /file1 /opt %environment export LISTEN_PORT=12345 export LC_ALL=C %post apt-get update && apt-get install -y netcat NOW=`date`echo " export NOW=\"${NOW}\"" >> $SINGULARITY_ENVIRONMENT %runscript echo "Container was created $NOW" echo "Arguments received: $*"exec echo "$@" %startscript nc -lp $LISTEN_PORT %test grep -q NAME=\"Ubuntu\"/etc/os-release if[ $? -eq 0 ];then echo "Container base is Ubuntu as expected." else echo "Container base is not Ubuntu." fi %labels Author d@sylabs.io Version v0.0.1 %help This is a demo container used to illustrate a def file that uses allsupported sections. }}} == Komponenten == * Header: * beschreibt KernOS bzw. Container mit Quelle * konfiguriert KernOS-Features * Linuxdistribution, genaue Version; Pakete, welche Teil der Installation sein müssen * Sections: * optional * kann mehrere Instanzen vorhandener Sections enthalten * Befehle werden von /bin/sh interpretiert und akzeptieren /bin/sh Optionen * ausgeführt zur Buildtime oder Runtime == Header == * Bootstrap: Gibt den Bootstrap-Agent an der zum Erstellen des Kernsystems genutzt wird. * möglich: library, docker, shub, localimage, yum, debootstrap, arch, busybox, zypper (genaueres in Doku: https://www.sylabs.io/guides/3.2/user-guide.pdf) * Beispiel für einen Header: {{{ Bootstrap: library From: debian:7 }}} oder {{{ Bootstrap: library From: ubuntu:18.04 }}} * Jeder Bootstrap-Agent bringt seine eigenen Quellen und Funktionen mit sich. Eine kurze Übersicht der Quellen gibt es [[https://wiki.init.mpg.de/IT4Science/SingularityContainerBauen#Quellen_f.2BAPw-r_Input|hier]] und eine ausführliche Beschreibung der Funktionen ist [[https://www.sylabs.io/guides/3.0/user-guide/appendix.html#build-library-module|hier]] zu finden. == Sections == * Wenn ein Befehl fehlschlägt, wird der Build-Prozess gestoppt. * Reihenfolge der Sections spielt keine Rolle * Es gibt verschiedenste Sections: %setup, %files, %post, %runscript, %startscript, %test, %labels, %help === %setup === * Befehle, die '''außerhalb den Containers auf dem Host-System''' ausgeführt werden, * werden ausgeführt, nachdem das KernOS den Container installiert worden ist, * Filesystem des Containers kann durch Umgebungsvariable referenziert werden: {{{$SINGULARITY_ROOTFS}}} * Beispiel: {{{ %setup touch /file1 touch${SINGULARITY_ROOTFS}/file2 }}} * file1 wird auf dem Host erstellt (/) * file2 wird im Container erstellt (/) * Für das Kopieren von Files wird %files empfohlen, da %setup als einzige Section mit '''erweiterten Privilegien (Root)''' ausgeführt wird. === %files === * zum '''Kopieren von Dateien aus dem Host-System''' in den Container * Jede Zeile besteht aus einem Paar von zwei Pfaden, welche den Quellpfad auf dem Host-System und den Zielpfad im Container angibt. * Der Zielpfad ist optional und ist gleich dem Quellpfad, falls dieser weggelassen werden sollte. * Beispiel: {{{ %files /file1 /file1 /opt }}} === %environment === * Hier werden Umgebungsvariablen definiert, welche '''während der Runtime''' zur Verfügung stehen. * Variablen, die hier definiert werden, stehen '''nicht''' während der Buildtime zur Verfügung (%post wäre hier die Wahl). * Es gelten die selben Konventionen wie in den .baschrc oder .profile Files. * Beispiel: {{{ %environment export LISTEN_PORT=12345 export LC_ALL=C }}} * Weitere Umgebungsvariablen können während der Runtime in %post definiert werden. * %environment schreibt die Umgebungsvariablen in {{{/.singularity.d/env/90-environment.sh}}} * In %post definierte Umgebungsvariablen landen in {{{/.singularity.d/env/91-environment.sh}}}. * %post-Umgebungsvariablen haben Vorrang gegenüber %environment-Variablen während der Laufzeit. === %post === * Befehle werden ausgeführt, '''nachdem das KernOS installiert''' wurde. * Hier werden Dateien heruntergeladen, neue Software und Libraries installiert, Config-Files erstellt, neue Verzeichnisse angelegt, usw. * Beispiel: {{{ %post apt-get update && apt-get install -y netcat NOW=`date` echo "export NOW=\"${NOW}\"" >> $SINGULARITY_ENVIRONMENT }}} * Um neue Umgebungsvariablen zu definieren, wird hier {{{$SINGULARITY_ENVIRONMENT}}} benutzt. * %post-Umgebungsvariablen haben Vorrang gegenüber %environment-Variablen während der Laufzeit === %runscript === * Befehle werden '''zur Runtime''' ausgeführt (durch singularity run oder exec) * Argumente, welche beim Start mitgegeben werden, werden hier genutzt * Beispiel: {{{ %runscript echo "Container was created $NOW" echo "Arguments received: $*" exec echo "$@" }}} * Konsolen-Output: {{{ $ ./my_container.sif Container was created Thu Dec 6 20:01:56 UTC 2018 Arguments received: }}} oder {{{ $ ./my_container.sif this that and the other Container was created Thu Dec 6 20:01:56 UTC 2018 Arguments received: this that and the other this that and the other }}} === %startscript === * Befehle werden ausgeführt, wenn '''instance start''' Befehl genutzt wird, welcher eine Container-Instanz startet. * Beispiel: {{{ %startscript nc -lp $LISTEN_PORT }}} * Container-Instanz lässt sich starten und stoppen mit: {{{ $ singularity instance start my_container.sif instance1 $ lsof | grep LISTEN $ singularity instance stop instance1 }}} === %test === * Befehle werden '''am Ende des Build-Prozesses''' ausgeführt. * alternativ auch über den test-Befehl ausführbar * Hier sollten Dinge wie BaseOS-Version, heruntergeladene Dateien und Softwarefunktionalität validiert werden. * Beispiel: {{{ %test grep -q NAME=\"U buntu\"/etc/os-release if[ $? -eq 0 ]; then echo "Container base is Ubuntu as expected." else echo "Container base is not Ubuntu." fi }}} * zum Überspringen des Testskripts beim Bauen eines Container den Parameter --notest benutzen: {{{$ sudo singularity build --notest my_container.sif my_container.def}}} === %labels === * Enthält '''Metadaten''', welche in das File /.singularity.d/labels.json im Container abgespeichert werden. * Jede Zeile besteht auch einem Name-Value-Paar. * Beispiel: {{{ %labels Author d@sylabs.io Version v0.0.1 }}} * Metadaten eines Containers (%labels) abrufbar mit: {{{ $ singularity inspect my_container.sif }}} === %help === * enthält einen beliebigen Text, welcher mit dem "run-help Befehl" aufgerufen werden kann: {{{$ singularity run-help my_container.sif}}} * Hier sollte eine Beschreibung des Containers, ähnlich einer Dokumentation, stehen. * Gerade im Sinne der Reproduzierbarkeit können hier die Versionen der Softwarekomponenten angegeben werden. * Es handelt sich also nur um einem Textbaustein, welcher keine weitere Funktion erfüllt, als als genau dieser angezeigt zu werden. Bei Änderungen des Containers sollte darauf geachtet werden, dass die $help-Section angepasst wird. * Beispiel: {{{ %help This is a demo container used to illustrate a def file that uses allsupported sections. }}} == Zeitliche Einordnung der Komponenten == * Außen vor sind die für Metadaten zuständige Sections %help und %labels, da deren zeitliche Abfolge irrelevant sind. * Unterteilung in Build-Prozess und Runtime: * Build-Prozess: * Zuerst findet das Bootstrapping statt, also das Erstellen eines KernOS im Container. * Als nächstes wird das Skript der %setup-Section mit root-Rechten auf dem Host-System ausgeführt. * Anschließende Schritte beeinflussen nur noch den Container. * Schließlich wird der Build-Prozess mit den Skripten der %files- und %post-Section beendet, ab jetzt ohne erweiterte Privilegien. * An den Build-Prozess schließt das Skript der %test-Section an. * Runtime: * Zuerst werden die Umgebungsvariablen durch die %environment-Section definiert. * Je nach Befehl wird das Skript der %runscript-Section (exec, run) oder das Skript der %startscript-Section (start) ausgeführt. {{attachment:definitionFileTime.png}} == Was sind Apps? == Durch die Nutzung von Sinularity-Apps baut man das Definition File modular auf. Somit kann man mehrere Skripte und Anwendungsfälle separat bearbeiten. Für weitere Informationen siehe [[https://wiki.init.mpg.de/IT4Science/SingularityApps|Singularity-Apps]]. == Beispiele für Definiton Files == Aus folgendem Definition File lässt sich ein Container bauen, welcher ein Ubuntu 14.04 enthält, sowie das x11-apps-Paket. Wird er gestartet, so wird xeyes ausgeführt. {{{ Bootstrap: library #Container stammt aus der Sylans.io Cloud Library From:ubuntu:14.04 #Läd den ubuntu-Container der Version 14.04. %post apt-get update && apt-get install -y x11-apps #installiert das x11-apps-Paket aus dem ubuntu 14.04 Paketarchiv %runscript xeyes #startet xeyes, wenn der container mit "$ singularity run" ausgeführt wird %labels Author thunert@cbs.mpg.de Version 1.0 %help This container holds an ubuntu 14.04 and x11-apps version 7.7+2. }}} Folgender Container enthält ein Ubuntu 18.04 aus dem Docker-Hub und ein bonnie++ Paket aus dem Ubuntu-Paketarchiv in der Version 1.97.3. Wenn der Container gestartet wird, wird aus den von bonnie++ gemessenen Ergebnissen ein CSV-File erstellt. {{{ Bootstrap: docker From: ubuntu:18.04 %post echo "BaseOS created" apt-get update && apt-get install -y bonnie++ %runscript echo "Container started" bonnie -r 2G -s 4G -f -b -n 0 > bonnieSingCont.csv %labels Author thunert@cbs.mpg.de Version 1.0 %help This container contains an ubuntu 18.04 and simply runs bonnie++. A CSV-File will be generated. }}} Der Container, welcher aus folgendem Definition File erstellt wird, enthält ein 18.04 Ubuntu mit Miniconda, Phyton und mne. Beim Starten des Containers wird eine bash gestartet in der man mit {{{$ conda activate mne}}} auf entsprechende mne-Tools zugreifen kann. {{{ Bootstrap: library From:ubuntu:18.04 %post export PATH=/opt/conda/bin:${PATH} apt-get update -y apt-get upgrade -y apt-get install -y curl sudo nano libxt-dev libglu1-mesa.dev wget wget -q https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O $HOME/miniconda.sh && bash $HOME/miniconda.sh -b -p $HOME/miniconda $HOME/miniconda/bin/conda update -n base -c defaults conda $HOME/miniconda/bin/conda init bash echo 'conda activate mne' >> $HOME/.bashrc curl -O https://raw.githubusercontent.com/blakecaldwell/mne-python/mayavi_linux/environment.yml $HOME/miniconda/bin/conda env create -f environment.yml $HOME/miniconda/envs/mne/bin/pip install https://api.github.com/repos/enthought/mayavi/zipball/226189a mkdir $HOME/shared %runscript export PATH=/miniconda/bin:${PATH} conda init bash bash %test $HOME/miniconda/bin/conda --version $HOME/miniconda/bin/python --version %help This container contains a version 4.6.14 of Miniconda, Version 3.7.3 of Python and mne based on a 18.04 Ubuntu. $ conda activate mne #to start mne %labels Author thunert@cbs.mpg.de Version v1.0 }}} Ein mit folgendem Definition File gebauter Container baut auf einen schon vorhandenen Container (siehe x11-apps Definition File Beispiel) auf. Zusätzlich wird hier Vim installiert. Startet man den Container, wird wieder xeyes ausgeführt. {{{ Bootstrap: localimage #baut auf einem lokal vorhandenen Container auf From: /path/to/container %post apt-get update && apt-get install -y vim %runscript xeyes %labels Author thunert@cbs.mpg.de Version 1.1 %help This container holds ubuntu 14.04 xtools and vim. }}}