Como executar compilações em contêineres do Docker da Jenkins

18

Estou tentando usar o Jenkins para criar um projeto C ++ em um contêiner do Docker. Não tenho nenhum problema em construir em Jenkins ou em um contêiner fora de Jenkins.

Abaixo está o que eu tentei. Estou omitindo o mapeamento de volumes para maior clareza.

Caso 1

O comando a seguir executa com êxito uma compilação em um shell.

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

No entanto, quando executado no Jenkins como uma etapa "executar shell", o Docker retorna o seguinte erro.

cannot enable tty mode on non tty input

Caso 2

O comando a seguir é semelhante ao anterior, mas desativa a interatividade.

docker run --rm $IMAGE make

Jenkins pode executar uma compilação com sucesso. No entanto, existem problemas sérios ao interromper uma compilação. A construção é imediatamente marcada como abortada, mas o contêiner continua em execução até que a construção seja concluída. Além disso, o recipiente não é removido após a saída.

Quando executado em um shell, o comando é construído com êxito, mas não é possível interrompê-lo. Além disso, o recipiente é removido após a saída.

Questão

Alguém saberia como executar compilações de maneira limpa nos contêineres do Docker da Jenkins e manter a capacidade de abortar compilações?

O uso de qualquer um dos plugins Jenkins não é uma opção, pois as chamadas do Docker estão dentro de scripts e não podem ser extraídas facilmente.

marcv81
fonte
11
Talvez com um trabalho pós-construção cuja tarefa seja remover o contêiner? E nos casos em que você aborta uma compilação, talvez você possa ter uma compilação especial que interrompa e remova todos os contêineres espúrios? Isso é subótimo, mas pelo menos é uma solução fácil de configurar. :-)
lgeorget 28/01
11
Isso não corresponde exatamente à minha definição de clean :) Mas agradeço a sugestão, e certamente é uma solução válida.
Marcv81

Respostas:

3

A maneira mais fácil de executar as construções do docker no Jenkins é usar o trabalho de pipeline. Ele possui muitos plug-ins embutidos que podem controlar o ambiente e os contêineres do Docker.

alguns exemplos são

    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.

Para obter mais informações: https://www.cloudbees.com/blog/orchestrating-workflows-jenkins-and-docker

velsim
fonte
2

Você pode implementar o seguinte fluxo de trabalho:

  1. crie um contêiner de janela de encaixe e especifique um nome para que você possa consultá-lo facilmente (por exemplo, em scripts)
  2. inicie e use algo como ponto de entrada que mantém o contêiner em execução
  3. Use docker exec container cmd ...para emitir seus comandos de construção e teste
  4. Pare o recipiente
  5. Retire a imagem

O docker exec ...é como um acesso shell remoto a uma máquina de rede. Por padrão, não é interativo e também não aloca um tty. Isso deve ser bom para compilar e executar conjuntos de testes. O comando encaminha corretamente o status de saída do comando executado dentro do contêiner.

Um trabalho de construção pode ser abortado através de:

  • docker stop container (envia TERM e KILL e aguarda no meio), ou
  • docker kill containerou mesmo
  • docker exec container pkill someexecutable

O fluxo de trabalho com comandos concretos:

$ 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

Para um exemplo real que usa esse fluxo de trabalho, você pode ver este arquivo .travis.yml , os scripts de IC reais , o script em execução no contêiner e os arquivos de encaixe das imagens usadas.

maxschlepzig
fonte