diff --git a/IUM_04.Konteneryzacja.ipynb b/IUM_04.Konteneryzacja.ipynb new file mode 100644 index 0000000..3cafe3b --- /dev/null +++ b/IUM_04.Konteneryzacja.ipynb @@ -0,0 +1,503 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# Konteneryzacja\n", + "Plan na dziś\n", + "\n", + "1. Konteneryzacja i Docker\n", + "2. Integracja Docker-Jenkins" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Konteneryzacja\n", + "- Konteneryzacja to metoda tworzenia lekkich, odizolowanych środowisk uruchomieniowych\n", + "- Różnica między konteneryzacją a maszynami wirtualnymi:\n", + " - Wirtualizacja na poziomie systemu operacyjnego a nie sprzętu\n", + " - Konteneryzacja jest lżejsza: kontener używa tego samego jądra (kernel) co system hosta - mniejszy narzut\n", + " - Konteneryzacja zapewnia gorszy stopień izolacji od hosta\n", + " - Dzięki dostępnym narzędziom i infrastrukturze kontenery są łatwiejsze w utrzymywaniu i bardziej przenośne\n", + "- Ułatwiają:\n", + " - rozwój,\n", + " - uruchamianie\n", + " - i dostarczanie\n", + "aplikacji.\n", + "- Konteneryzacja to nie tylko Docker:\n", + " - chroot\n", + " - Solaris Containers\n", + " - LXC (Linux Containers)\n", + " - OpenVZ\n", + " - Windows containers\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.1 Docker\n", + "- Najpopularniejszy obecnie system konteneryzacji\n", + "- Działa w m.in. na systemach Linux, Windows i Max OS\n", + "- Udostępnia narzędzia i serwisy ułatwiające korzystanie, zarządzanie i dzielenie się kontenerami\n", + "- Docker umożliwia stworzenie paczki zawierającej sam program jak i środowisko, w którym ma być on uruchomiony\n", + " \n", + "- Dokumentacja: https://docs.docker.com/get-started/\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.1 Terminologia\n", + " - *Container* (kontener) - instancja obrazu. Może być uruchomiona, zatrzymana. Stan kontenera można zapisać tworząc nowy obraz. Uruchomienie kontenera zazwyczaj zajmuje mało czasu.\n", + " - *Image* (obraz) - niezmienny (readonly) przepis na stworzenie kontenera. Obrazy można ściągnąć lub udostępnić za pośrednictem *rejestru*. Budowanie obrazu trwa zazwyczaj długo.\n", + " - *Dockerfile* - plik tekstowy zawierający przepis na zbudowanie obrazu\n", + " - *Docker registry* - rodzaj repozytorium, przechowującego obrazy dockera\n", + " - *Docker Hub* - publiczne *Docker registry*, z którego każdy może pobrać potrzebne mu obrazy oraz publikować swoje" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.2 Jak zacząć?\n", + " - Na komputerach w laboratoriach: https://laboratoria.wmi.amu.edu.pl/en/issues/docker/\n", + " - Lokalnie: [instalacja](https://docs.docker.com/engine/install/)\n", + " - Możliwa zarówno pod Linux, Windows i MacOS.\n", + " - Kontenery Linuxowe można uruchamiać również pod Windowsem (za pomocą Docker Desktop lub WSL 2 (Windows Subsystem for Linux). Pod spodem oba używają maszyny wirtualnej (Hyper-V) z Linuxem, w której uruchamiane są kontenery [link](https://www.docker.com/blog/docker-hearts-wsl-2/)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.3 Podstawowe polecenia\n", + "- ```docker help [polecenie]``` - wyświetla listę dostępnych poleceń dockera lub opis podanego polecenia. Rozbudowana dokumentacja poleceń: https://docs.docker.com/engine/reference/commandline/docker/\n", + "- ```docker run``` - uruchamia istniejący obraz tworząc kontener. Przykładowe wywołania:\n", + " - ```docker run -i -t ubuntu```
\n", + " Uruchamia kontener z obrazu \"ubuntu\", allokuje terminal (`-t`) i ustawia tryb \"interaktywny\" (`-i`), dzięki czemu dostajemy terminal \"wenątrz\" kontenera i możemy wywoływać w nim polecenia\n", + "\n", + " - ```docker run -p 8080:8080 jenkins/jenkins:lts```
\n", + " Uruchomi kontener z Jenkinsem, w wersji \"LTS\". Jeśli obraz Jenkins nie był wcześniej zbudowany/pobrany na lokalną maszynę, automatycznie zostanie pobrany z [Docker Hub](https://hub.docker.com/r/jenkins/jenkins).\n", + " Port 8080 konenera zostanie powiązany z portem 8080 hosta. Dzięki temu będziemy mogli w przeglądarce dostać się do Jenkinsa pod adresem http://localhost:8080\n", + " Ważne: po zatrzymaniu kontenera \n", + "- ```docker build [OPTIONS] PATH | URL | -``` - buduje obraz na podstawie pliku Dockerfile i kontekstu (plików dostępnych podczas budowania). Przykład:
\n", + " - ```docker build -t tzietkiewicz/helloworld:1.0 .```
\n", + " buduje obraz przekazując bieżący katalog (`.`) jako kontekst i korzystając z pliku Dockerfile znajdującego się tamże. Obraz zostanie otagowany (`-t`) tagiem `tzietkiewicz/helloworld` z wersją `1.0`\n", + "- ```docker images``` - listuje dostępne lokalnie obrazy\n", + "- ```docker ps``` - listuje uruchomione/zatrzymane kontenery\n", + "- ```docker stop CONTAINER_ID``` - zatrzymuje kontener. Uruchomione w nim procesy zostają wyłączone (`SIGTERM` -> `SIGKILL`)\n", + "- ```docker start CONTAINER_ID``` - uruchamia ponownie kontener\n", + "- ```docker system prune``` - usuwa nieużywane obrazy i kontenery, zazwyczaj zwalniając sporo miejsca na dysku" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.4 Interakcja/komunikacja z kontenerem\n", + " - Poprzez terminal\n", + " - Poprzez `docker exec` - wywołanie polecenia w działającym kontenerze\n", + " - Poprzez port zmapowany przez flagę `-p` (np. REST API albo interfejs w przegląrce)\n", + " - Przez system plików: podmontowanie katalogów hosta w kontenerze poprzez flagę `-v` [dokumentacja](https://docs.docker.com/engine/reference/commandline/run/#mount-volume--v---read-only)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Zadanie 1 [na zajęciach]\n", + "1. Zainstaluj Docker (lub skorzystaj z https://laboratoria.wmi.amu.edu.pl/en/issues/docker/)\n", + "2. Uruchom obraz `ubuntu` w trybie interaktywnym z terminalem (`docker run -ti ubuntu`)\n", + "\n", + "Poniższe punkty wywołujemy wewnątrz kontenera (w otwartym właśnie terminalu):\n", + "\n", + "3. Jaka wersja Ubuntu działa w kontenerze? (polecenie `cat /etc/issue`)\n", + "4. Jaki użytkownik wywołuje polecenia? (polecenie `whoami`)\n", + "5. Jaki jest bieżący katalog? (polecenie `pwd`)\n", + "5. Jaki procesor jest widoczny w środku kontenera? Czy jest to procesor Twojej maszyny? (`lscpu`)\n", + "6. Ile wolnego miejsca na dysku jest widoczne wewnątrz kontenera (`df -h`)? Czy jest to zgodne z tym, co pokazuje maszyna hosta?\n", + "7. Sprawdź ile dostępnej pamięci RAM widać w konenerze (`free -h`). Czy zgadza się to z wynikiem na maszynie hosta?\n", + "8. Spróbuj uruchomić jedno z popularnych narzędzi Linuksowych, dostępnych na maszynie hosta (np. `vim`, `less`, `htop`). Czy udało się je uruchomić?\n", + "9. Zainstaluj w kontenerze jedno z brakujących narzędzi, np: `apt update; apt install htop`\n", + "10. Uruchom następujące polecenie:
\n", + "`while true; do date > time.log; sleep 1; done`\n", + "będzie ono co sekundę zapisywać bieżący timestamp w pliku time.log\n", + "\n", + "Poniższe polecenia wykonujemy na zewnątrz kontenera (otwórz w tym celu nową konsolę):\n", + "\n", + "11. Sprawdź ID uruchomionego kontenera (`docker ps`) i zatrzymaj go (`docker stop`)\n", + "12. Sprawdź co się stało w oknie z konsolą kontenera\n", + "13. Uruchom kontener jeszcze raz (`docker start`). Gdzie jest nasza konsola?!!\n", + "14. Żeby otrzymać konsolę, wykonaj jedno z poniższych:\n", + " - zatrzymaj kontener i uruchom jeszcze raz z flagą `-i`\n", + " - uruchom polecenie \"bash\" w kontenerze za pomocą polecenia `docker exec -ti CONTAINER_ID bash` - pozwala ono uruchomić dowolne polecenie w działającym kontenerze.\n", + "15. Czy polecenie `while true; do date > time.log; sleep 1; done` wciąż działa? Sprawdź ostatni timestamp zapisany do pliku `time.log`" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1.4 Dockerfile\n", + "\n", + " - Dokumentacja: https://docs.docker.com/engine/reference/builder/\n", + "\n", + " - Dockerfile składa się z serii poleceń.\n", + " - Polecenia dockera są pisane WIELKIMI LITERAMI\n", + " - Wywołanie każdego polecenia tworzy nową warstwę (*layer*)\n", + " - Jeśli zbudowaliśmy obraz a potem zmieniliśmy jedno z poleceń / dodaliśmy nowe, to przebudowane zostaną tylko warstwy od zmienionej w dół (osczędność czasu i zasobów)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Przykładowy Dockerfile:\n", + "```Dockerfile\n", + "# Nasz obraz będzie dzidziczył z obrazu Ubuntu w wersji latest\n", + "FROM ubuntu:latest\n", + "\n", + "# Instalujemy niezbędne zależności. Zwróć uwagę na flagę \"-y\" (assume yes)\n", + "RUN apt update && apt install -y figlet\n", + "\n", + "# Stwórzmy w kontenerze (jeśli nie istnieje) katalog /app i przejdźmy do niego (wszystkie kolejne polecenia RUN, CMD, ENTRYPOINT, COPY i ADD będą w nim wykonywane)\n", + "WORKDIR /app\n", + "\n", + "# Skopiujmy nasz skrypt do katalogu /app w kontenerze\n", + "COPY ./figlet-loop.sh ./\n", + "\n", + "# Domyślne polecenie, które zostanie uruchomione w kontenerze po jego starcie\n", + "CMD ./figlet-loop.sh\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zawartość pliku `figlet-loop.sh`:\n", + "```bash\n", + "#!/bin/bash\n", + "while read line; do\n", + "\tfiglet \"$line\"\n", + "done\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Budujemy obraz:\n", + "```bash\n", + "docker build -t figlet-loop .\n", + "```\n", + "\n", + "```\n", + "Sending build context to Docker daemon 3.072kB\n", + "Step 1/5 : FROM ubuntu:latest\n", + " ---> 94e814e2efa8\n", + "Step 2/5 : RUN apt update && apt install -y figlet\n", + "\n", + " ---> Running in ba8b14deeeca\n", + "Get:1 http://archive.ubuntu.com/ubuntu bionic InRelease [242 kB]\n", + "[...]\n", + "Get:18 http://security.ubuntu.com/ubuntu bionic-security/universe amd64 Packages [1402 kB]\n", + "Fetched 22.3 MB in 3s (8343 kB/s)\n", + "Reading package lists...\n", + "Building dependency tree...\n", + "Reading state information...\n", + "[...]\n", + "Reading package lists...\n", + "Building dependency tree...\n", + "Reading state information...\n", + "The following NEW packages will be installed:\n", + " figlet\n", + "0 upgraded, 1 newly installed, 0 to remove and 50 not upgraded.\n", + "Need to get 133 kB of archives.\n", + "After this operation, 752 kB of additional disk space will be used.\n", + "Get:1 http://archive.ubuntu.com/ubuntu bionic/universe amd64 figlet amd64 2.2.5-3 [133 kB]\n", + "debconf: delaying package configuration, since apt-utils is not installed\n", + "Fetched 133 kB in 0s (605 kB/s)\n", + "Selecting previously unselected package figlet.\n", + "(Reading database ... 4039 files and directories currently installed.)\n", + "Preparing to unpack .../figlet_2.2.5-3_amd64.deb ...\n", + "Unpacking figlet (2.2.5-3) ...\n", + "Setting up figlet (2.2.5-3) ...\n", + "update-alternatives: using /usr/bin/figlet-figlet to provide /usr/bin/figlet (figlet) in auto mode\n", + "update-alternatives: warning: skip creation of /usr/share/man/man6/figlet.6.gz because associated file /usr/share/man/man6/figlet-figlet.6.gz (of link group figlet) doesn't exist\n", + "Removing intermediate container ba8b14deeeca\n", + " ---> 30470dc0bd47\n", + "Step 3/5 : WORKDIR /app\n", + " ---> Running in 47ca74217790\n", + "Removing intermediate container 47ca74217790\n", + " ---> 0f352dfc965d\n", + "Step 4/5 : COPY ./figlet-loop.sh ./\n", + " ---> 450ba60dc50d\n", + "Step 5/5 : CMD ./figlet-loop.sh\n", + " ---> Running in 38f83a71b1a9\n", + "Removing intermediate container 38f83a71b1a9\n", + " ---> c6d81a065621\n", + "Successfully built figlet-loop:latest\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Uruchamiamy:\n", + "```\n", + "docker run -ti figlet-loop\n", + "Hello World!\n", + " _ _ _ _ __ __ _ _ _ \n", + "| | | | ___| | | ___ \\ \\ / /__ _ __| | __| | |\n", + "| |_| |/ _ \\ | |/ _ \\ \\ \\ /\\ / / _ \\| '__| |/ _` | |\n", + "| _ | __/ | | (_) | \\ V V / (_) | | | | (_| |_|\n", + "|_| |_|\\___|_|_|\\___/ \\_/\\_/ \\___/|_| |_|\\__,_(_)\n", + "\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Zamiast domyślnego polecenia (`figlet-loop.sh`) uruchommy bash, żeby sprawdzić, co jest w naszym kontenerze:\n", + "```bash\n", + "docker run -ti figlet-loop:latest bash\n", + "root@a44c68ce835e:/app# pwd\n", + "/app\n", + "root@a44c68ce835e:/app# ls -l\n", + "total 4\n", + "-rwxrwxr-x 1 root root 53 Mar 28 22:33 figlet-loop.sh\n", + "root@a44c68ce835e:/app# \n", + "\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Zadanie 2. [10 pkt]\n", + "1. Napisz prosty Dockerfile, który zdefinuje środowisko potrzebne do wywołania poleceń stworzonych na zajęciach \"2. Dane\". Przypuszczalnie wystarczy, że zainstalujesz zależności takie jak kaggle czy pandas, np: \n", + "```bash\n", + "!pip install --user kaggle\n", + "!pip install --user pandas\n", + "```\n", + "Niech zdefiniowany przez Ciebie obraz dziedziczy z jakiegoś popoularneg obrazu, np. `ubuntu`\n", + "Umieść Dockerfile w głównym katalogu repozytorium ze skryptami stworzonymi na zajęciach 2.\n", + "\n", + "2. Zbuduj obraz korzystając z polecenia `docker build .`\n", + " Na końcu otrzymasz id obrazu, który powstał\n", + "3. Uruchom kontener z terminalem `docker run -ti IMAGE_ID` podając ID obrazu, które otrzymałeś w poleceniu 2.\n", + "4. Spróbuj uruchomić jeden z twoich skryptów w kontenerze. Jeśli brakuje jakiś zależności: możesz spróbować zainstalować je interaktywnie w konsoli. W ten sposób będziesz wiedział jakie polecenia dodać do Dockerfile.\n", + "5. Utwórz bezpłatne konto na https://hub.docker.com/\n", + "6. Po zalogowaniu stwórz nowe repozytorium (https://hub.docker.com/repository/create), możesz nazwać je np. `ium`\n", + "7. W ustawieniach docker hub wygeneruj \"Access token\" (https://hub.docker.com/settings/security)\n", + "8. Uruchom `docker login --username TWÓJ_DOCKER_ID` i podaj stworzony w poprzednim kroku \"Access token\"\n", + "9. Dodaj tag do obrazu stworzonego 2 punkcie 3. Dzięki temu będzie można go opublikować: `docker tag IMAGE_ID TWÓJ_DOCKER_ID/ium:NUMER_WERSJI`. Mogliśmy otagować obraz na etapie jego budowania (flaga `-t`), ale wtedy nie znaliśmy jeszcze nazwy użytkownika i repozytorium z Docker Hub.\n", + "10. Teraz możesz wypchnąć swój otagowany obraz do repozytorium: `docker push TWÓJ_DOCKER_ID/ium:NUMER_WERSJI`\n", + "11. Twój obraz powinien być widoczny na Docker Hub. Inni mogą go teraz znaleźć na [Docker Hub](https://hub.docker.com/search?q=&type=image), np.:
\n", + "https://hub.docker.com/r/tzietkiewicz/ium
\n", + "oraz uruchomić wywołując: `docker run TWÓJ_DOCKER_ID/ium:NUMER_WERSJI`, np.:
\n", + "```docker run tzietkiewicz/ium```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. Integracja Docker-Jenkins" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.1 Jenkins\n", + "Jenkins może działać na wielu systemach operacyjnych:\n", + " - Linux\n", + " - Windows\n", + " - MacOS" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.1 Jenkins - Terminologia (https://www.jenkins.io/doc/book/glossary/):\n", + " - **Agent**: An agent is typically a machine, or container, which connects to a Jenkins controller and executes tasks when directed by the controller\n", + " - **Controller**: The central, coordinating process which stores configuration, loads plugins, and renders the various user interfaces for Jenkins\n", + " - **Master**: A deprecated term, synonymous with Controller.\n", + " - **Node**: A machine which is part of the Jenkins environment and capable of executing Pipelines or Projects. Both the Controller and Agents are considered to be Nodes.\n", + " - **Executor**: A slot for execution of work defined by a Pipeline or Project on a Node. A Node may have zero or more Executors configured which corresponds to how many concurrent Projects or Pipelines are able to execute on that Node." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Główna instancja Jenkinsa (tzw. *Controller* aka. *Master*) może mieć podłączonych kilka węzłów (\"nodes\") typu \"slave\".\n", + " - *Controller* jest odpowiedzialny za interakcję z użytkownikiem, rozdzielanie zadań dla między agentów\n", + " - Zadania (\"builds\") są wykonywane na jednym z \"Agentów\". Node, na którym jest uruchomiony \"Controller\" może działać również jako \"Agent\"\n", + " - Każdy węzeł może działać pod kontrolą innego systemu operacyjnego. Dzięki temu możemy wykonywać zadania (albo ich części) w różnych środowiskach\n", + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " - Do definiowana gdzie może być wykonana dana część pipeline, służy sekcja [agent / node](https://www.jenkins.io/doc/book/pipeline/syntax/#agent). Poniższy kod wywoła sie tylko na węźle/węzłach \"myAgent\":\n", + " ```groovy\n", + " node(\"myAgent\") {\n", + " stage(\"One\"){\n", + " echo 'hello'\n", + " }\n", + "}\n", + " ```" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + " ## 2.2 Docker w Jenkins\n", + " \n", + "\n", + " \n", + " - Więcej informacji: https://www.jenkins.io/doc/book/pipeline/docker/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2 Przykłady pipeline\n", + "Używanie gotowego obrazu:\n", + " - Scrippted pipeline:\n", + "```groovy\n", + " node {\n", + " docker.image('ubuntu:latest').inside {\n", + " stage('Test') {\n", + " sh 'cat /etc/issue'\n", + " }\n", + " }\n", + " }\n", + "```\n", + " - Declarative:\n", + " ```groovy\n", + " pipeline {\n", + " agent {\n", + " docker { image 'ubuntu:latest' }\n", + " }\n", + " stages {\n", + " stage('Test') {\n", + " steps {\n", + " sh 'cat /etc/issue'\n", + " }\n", + " }\n", + " }\n", + " }\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2.2 Przykłady pipeline\n", + "Budowanie obrazu z Dockerfile:\n", + " - Scrippted pipeline:\n", + " ```groovy\n", + " node {\n", + " checkout scm\n", + " //Pierwszy argument to tag, który zostania nadany zbudowanemu obrazowi\n", + " //Jeśli chcemy użyć Dockerfile z innej ścieżki niż ./Dockerfile, możemy ją podać jako drugi argument\n", + " def testImage = docker.build(\"test-image\", \"./dockerfiles/test\") \n", + "\n", + " //Wszystkie polecenia poniżej wykonają się w kontenerze, z podmontowanym Workspace Jenkinsa\n", + " testImage.inside {\n", + " sh 'make test'\n", + " }\n", + " }\n", + "```\n", + " - Declarative:\n", + " ```groovy\n", + " pipeline {\n", + " agent { \n", + " dockerfile true \n", + " }\n", + " stages {\n", + " stage('Test') {\n", + " steps {\n", + " sh 'cat /etc/issue'\n", + " }\n", + " }\n", + " }\n", + "}\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Zadanie 3. [5 pkt]\n", + "1. Dodaj do stworzonego na poprzednich zajęciach Jenkinsfile opisującego pipeline \"s123456-create-dataset\" sekcję \"Docker\", która spowoduje, że kroki będą wywoływane wewnątrz kontenera zdefiniowanego w pliku Dockerfile stworzonym w zadaniu 2.\n", + "2. Dodaj do stworzonego na poprzednich zajęciach Jenkinsfile opisującego pipeline \"s123456-dataset-stats\" sekcję \"Docker\", która spowoduje, że kroki będą wywoływane wewnątrz kontenera uruchomionego z obrazu, który w zadaniu 2. opublikowałeś na Docker Hub." + ] + } + ], + "metadata": { + "celltoolbar": "Slideshow", + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": false, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/IUM_04/MacOS_logo.svg b/IUM_04/MacOS_logo.svg new file mode 100644 index 0000000..3ee4fe2 --- /dev/null +++ b/IUM_04/MacOS_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/IUM_04/Tux.svg b/IUM_04/Tux.svg new file mode 100644 index 0000000..c0a92e0 --- /dev/null +++ b/IUM_04/Tux.svg @@ -0,0 +1,1532 @@ + + + + Tux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Tux + 20 June 2012 + + + Garrett LeSage + + + + + + Larry Ewing, the creator of the original Tux graphic + + + + + tux + Linux + penguin + logo + + + + + Larry Ewing, Garrett LeSage + + + https://github.com/garrett/Tux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IUM_04/Windows_logo_-_2012_derivative.svg b/IUM_04/Windows_logo_-_2012_derivative.svg new file mode 100644 index 0000000..19b5cc0 --- /dev/null +++ b/IUM_04/Windows_logo_-_2012_derivative.svg @@ -0,0 +1 @@ + diff --git a/IUM_04/docker-jenkins.png b/IUM_04/docker-jenkins.png new file mode 100644 index 0000000..8edb0ff Binary files /dev/null and b/IUM_04/docker-jenkins.png differ diff --git a/IUM_04/jenkins.svg b/IUM_04/jenkins.svg new file mode 100644 index 0000000..0529fff --- /dev/null +++ b/IUM_04/jenkins.svg @@ -0,0 +1,283 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/IUM_04/master-slave.png b/IUM_04/master-slave.png new file mode 100644 index 0000000..04f47e8 Binary files /dev/null and b/IUM_04/master-slave.png differ diff --git a/IUM_04/master-slave.svg b/IUM_04/master-slave.svg new file mode 100644 index 0000000..6ab5c02 --- /dev/null +++ b/IUM_04/master-slave.svg @@ -0,0 +1,8891 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Master + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MacosSlaves + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WindowsSlaves + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinuxSlaves + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +