Jak uruchamiać kompilacje w kontenerach Docker od Jenkins

18

Próbuję użyć Jenkinsa do zbudowania projektu C ++ w kontenerze Docker. Nie mam problemu z budowaniem w Jenkins ani budowaniem w kontenerze poza Jenkins.

Poniżej próbowałem. Dla jasności pomijam mapowanie woluminów.

Przypadek 1

Następujące polecenie z powodzeniem uruchamia kompilację w powłoce.

docker run --rm --interactive=true --tty=true $IMAGE make

Jednak po uruchomieniu w Jenkinsie jako „wykonanie powłoki” krok Docker zwraca następujący błąd.

cannot enable tty mode on non tty input

Przypadek 2

Poniższe polecenie jest podobne do poprzedniego, ale wyłącza interaktywność.

docker run --rm $IMAGE make

Jenkins może pomyślnie uruchomić kompilację. Istnieją jednak poważne problemy podczas przerywania kompilacji. Kompilacja jest natychmiast oznaczana jako przerwana, ale kontener działa, dopóki kompilacja nie zostanie ukończona. Również pojemnik nie jest usuwany po wyjściu.

Po uruchomieniu w powłoce polecenie buduje się pomyślnie, ale nie można go przerwać. Również pojemnik jest wyjmowany po wyjściu.

Pytanie

Czy ktokolwiek wiedziałby, jak czysto uruchamiać kompilacje w kontenerach Docker od Jenkinsa i zachować możliwość przerywania kompilacji?

Użycie żadnej wtyczki Jenkins nie jest opcją, ponieważ wywołania Docker znajdują się w skryptach i nie można ich łatwo wyodrębnić.

marcv81
źródło
1
Może z zadaniem po kompilacji, którego zadaniem jest usunięcie kontenera? A w przypadkach, w których przerywasz kompilację, może możesz mieć specjalną kompilację, która zatrzymuje i usuwa wszystkie fałszywe pojemniki? Jest to nieoptymalne, ale przynajmniej jest to obejście łatwe do skonfigurowania. :-)
lgeorget
1
To nie do końca pasuje do mojej definicji czystości :) Ale doceniam sugestię i na pewno jest to poprawne obejście.
marcv81

Odpowiedzi:

3

Najprostszym sposobem na uruchomienie kompilacji dokerów w Jenkins jest użycie zadania potoku. Ma wiele wbudowanych wtyczek, które mogą kontrolować twoje środowisko Dockera i kontenery.

kilka przykładów to

    docker.image("image-name").run() -Runs the container from the image 
    docker.image("image-name").inside(){//your commands} -Runs your commands inside the docker container and also removes your container as soon as your commands are executed.

Aby uzyskać więcej informacji: https://www.cloudbees.com/blog/orchestrating-workflows-jenkins-and-docker

velsim
źródło
2

Możesz wdrożyć następujący przepływ pracy:

  1. utwórz kontener dokowania i podaj nazwę, aby łatwo do niego odwoływać się (np. w skryptach)
  2. uruchom go i użyj czegoś jako punktu wejścia, który utrzyma działanie kontenera
  3. Służy docker exec container cmd ...do wydawania poleceń kompilacji i testowania
  4. Zatrzymaj pojemnik
  5. Usuń obraz

To docker exec ...jest jak zdalny dostęp powłoki do komputera sieciowego. Domyślnie nie jest interaktywny i nie przydziela tty. Powinno to być odpowiednie do kompilowania i wykonywania zestawów testowych. Polecenie poprawnie przekazuje status wyjścia polecenia wykonanego w kontenerze.

Zadanie kompilacji można następnie przerwać przez:

  • docker stop container (wysyła TERM i KILL i czeka pomiędzy), lub
  • docker kill container, lub nawet
  • docker exec container pkill someexecutable

Przepływ pracy z konkretnymi poleceniami:

$ docker create --name cxx-devel \
    -v $HOME/src:/srv/src:ro -v $HOME/build:/srv/build \
    gsauthof/fedora-cxx-devel:23
$ docker start cxx-devel     # <- entrypoint is /usr/bin/sleep infinity
$ docker exec cxx-devel /srv/src/projecta/build.sh
$ docker exec cxx-devel /srv/src/projecta/check.sh
$ docker stop cxx-devel
$ docker rm cxx-devel

Dla prawdziwego przykładu, który korzysta z tego przepływu pracy, możesz zobaczyć ten plik .travis.yml , rzeczywiste skrypty CI , skrypt działający w kontenerze i pliki dokera używanych obrazów.

maxschlepzig
źródło