Ejtools
Grupo: Lucas Mattioli e Jonathan Rufino
Gerência de Configuração de Software
editarEsse trabalho tem como objetivo realizar contribuições relacionadas à Gerência de Configuração de Software ao software Ejtools.
Tais contribuições são referentes ao projeto da disciplina de Gerência de Configuração de Software, 7º Semestre, Universidade de Brasília - FGA.
Pagina da disciplina disponível em Gerência de Configuração de Software - UnB/FGA
Projeto
editarO Ejtools é um conjunto de ferramentas independentes que tem como objetivo principal auxiliar atividades práticas de programação, incluindo maratonas/competições de programação. O projeto é formado por 7 módulos, onde apenas um (core) não é uma ferramenta:
- Checker: módulo de correção automática das soluções de problemas propostas;
- Client: módulo de envio de soluções para um servidor;
- Core: biblioteca estática com funcionalidades comuns;
- Problems: módulo de formatação e instalação de problemas;
- Scoreboard: módulo que representa o placar de uma competição de programação;
- Server: servidor que recebe soluções propostas via rede;
- Users: scripts para cadastro de usuários.
Para mais informações sobre o projeto, acesse os links a seguir:
Ejtools
Repositório da Disciplina
Objetivos
editarOs dois principais objetivos a serem abordados pelo grupo neste projeto são:
- Migração da integração contínua para o GitLab-CI;
- Empacotamento do módulo Checker.
Cronograma
editarPeríodo | Objetivo |
---|---|
20/04 a 26/04 | Definição do projeto e escopo |
27/04 a 03/05 | Estudo e início dos testes do módulo Checker |
04/05 a 10/05 | Continuação de testes do módulo Checker |
11/05 a 17/05 | Finalização dos testes propostos para o módulo Checker |
18/05 a 24/05 | Estudo da ferramenta GitLab-CI e início da integração contínua |
25/05 a 31/05 | Implantação da integração contínua |
01/06 a 07/06 | Estudar/pesquisar ferramentas para empacotamento do módulo Checker |
08/06 a 14/06 | Continuação de empacotamento do módulo Checker |
15/06 a 21/06 | Finalização do empacotamento e entrega final do projeto |
Integração Contínua - GitLab-CI
editarConfiguração
editarA integração contínua oferecida pelo GitLab é bem simples de ser configurada. É necessário, a princípio, apenas um arquivo de configuração YAML chamado .gitlab-ci.yml no diretório raiz do projeto. Este arquivo dá diretrizes aos Runners configurados no dado projeto. A estrutura do arquivo é a seguinte:
before_script:
- apt-get update -qq && apt-get install -y -qq sqlite3 libsqlite3-dev nodejs
- ruby -v
- which ruby
- gem install bundler --no-ri --no-rdoc
- bundle install --jobs $(nproc) "${FLAGS[@]}"
rspec:
script:
- bundle exec rspec
rubocop:
script:
- bundle exec rubocop
Os blocos mais externos (before_script, rspec e rubocop) são denominados jobs. Dentro deles, são definidos os comandos a serem executados pelos Runners configurados e devem, sempre, conter a keyword script. O job nomeado como before_script é, no entanto, um job especial; não há necessidade de definir a keyword script para que seus comandos sejam executados. Sua função é executar todos os comandos referentes a dependências, para que os outros jobs possam ser completados com sucesso. Existem muitos outros jobs "especiais" além do before_script; caso queira checá-los, e entender um pouco mais da sintaxe do arquivo .gitlab-ci.yml, cheque o link a seguir: Configuration of your builds with .gitlab-ci.yml
Atualmente, o arquivo .gitlab-ci.yml do projeto ejtools se encontra da seguinte maneira:
image: jonathanrufino/ejtoolsdocker:base
before_script:
- chmod +x run_ejproblem_tests.sh
- python2.7 -m pip install flake8
tests:
script:
- echo "Checking flake8..."
- python2.7 -m flake8 .
- echo "Running tests..."
- ./run_ejproblem_tests.sh
- echo "Finished."
A execução de todos os testes do projeto está configurada no script shell run_ejproblem_tests.sh. Assim, o objetivo "descrito" por este arquivo é: a cada push (ou seja, a cada alteração de código) para o repositório, todos os testes devem estar passando e o código deve estar seguindo o estilo de código PEP8, este que é, nesse caso, verificado pelo flake8.
Docker
editarPara este projeto utilizou-se um runner do tipo docker runner, desta forma as builds sempre serão executadas em um ambiente limpo, visto que a cada execução um novo container é criado a partir da imagem base.
Como a única dependência do projeto para construção de build é o python2.7
, foi utilizada a imagem python:2.7
Para utilizar a imagem docker é necessário disponibilizá-la no Docker Hub, para isso crie uma conta e em seguida um repositório. Após criar o repositório:
Primeiro instale o docker:
$ sudo apt-get install docker
ou
$ sudo apt-get install docker.io
Em seguida baixe a imagem do python:2.7:
$ docker pull python:2.7
Para acessar a imagem baixada podemos utilizar:
$ docker run -t -i python:2.7 /bin/bash
A partir desse momento já poderíamos instalar outros pacotes desejados, no nosso caso seria possível já deixar instalada a ferramenta flake8
, mas para fins de demonstração deixamos a instalação para o script de integração contínua.
root@392b50f0ffd3:/#
Perceba que é exibido o usuário root e o ID do container criado, este ID será utilizado para salvar e compartilhar a imagem. Para realizar o compartilhamento devemos "deslogar" da imagem com Ctrl + D
.
$ docker commit -m "Creating docker image" -a "Jonathan Rufino" 392b50f0ffd3 jonathanrufino/ejtoolsdocker:base
$ docker push jonathanrufino/ejtoolsdocker
Pronto. A imagem já pode ser utilizada pelo nosso docker, para isso adicione a linha image: jonathanrufino/ejtoolsdocker:base
no arquivo .gitlab-ci.yml
.
Esta imagem foi criada com a tag base
apenas para indicar que a imagem original não foi alterada.
Imagem utilizada: https://hub.docker.com/r/jonathanrufino/ejtoolsdocker/
Runner
editarPara a realização da integração contínua é necessária a utilização de um Runner. Um runner' é uma máquina virtual isolada que pega builds por meio da API do Gitlab. Além disso é capaz de testar qualquer linguagem de programação.
Para a criação do runner foi utilizado o seguinte tutorial https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/install/linux-repository.md .
Durante o registro do runner é que definimos o nosso docker criado anteriormente, no passo de seleção do executor, escolha docker e forneça as informações necessárias
Empacotamento Debian
editarFerramentas Utilizadas
editarPara realizar o empacotamento debian(.deb) da aplicação, é necessário instalar as ferramentas dh_make e build-essential. Estas ferramentas podem ser instaladas como mostrado à seguir:
$ sudo apt-get install dh-make
$ sudo apt-get install build-essential
Com isso, já é possível realizar o procedimento de empacotamento e obter um pacote .deb para a instalação automatizada da ferramenta.
Processo de Empacotamento
editarPrimeiro, deve-se realizar o clone do projeto que será empacotado, neste caso, ejtools, a url é git@gitlab.com:ejudge/ejtools.git. Recomenda-se criar uma pasta específica para realizar o empacotamento, visto que são gerados vários arquivos durante o processo.
$ mkdir empacotamento/
$ cd empacotamento/
$ git clone git@gitlab.com:ejudge/ejtools.git
Como será realizado o empacotamento apenas do módulo checker, podemos mover esta pasta para outro diretório para manter o ambiente mais organizado.
$ cd ejtools/
$ cp -r checker/ ../ejchecker-0.1/
A partir deste ponto, vamos assumir que a nossa pasta raíz é empacotamento/
user:~/empacotamento/ pwd
/home/user/empacotamento
Tambem é necessário nomear a pasta de acordo com as especificações do dh_make, que consiste no nome do pacote e sua versão, assim renomeamos a pasta checker para ejchecker-0.1. Outro requisito do dh_make é a utilização de um arquivo compactado, para isto podemos fazer:
$ tar -zcvf ejchecker-0.1.tar.gz ejchecker-0.1/
Com isso já temos a estrutura utilizada pelo dh_make para a geração de uma estrutura básica de configuração de empacotamento. Podemos então gerar tal estrutura:
$ cd ejchecker-0.1/
$ dh_make -f ../ejchecker-0.1.tar.gz
Logo em seguida pode-se verificar a criação de um diretório debian/. Esta pasta contém os arquivos necessários para a realização do empacotamento. Porém dentro da pasta debian/ são criados alguns arquivos que não são necessários e podemos removê-los:
$ cd debian/
$ rm *.ex *.EX
Para realizar a autenticação do pacote é necessário gerar um par de chaves assimétricas no computador em que está sendo gerado o pacote. Uma forma de gerar tal chave é com a ferramenta gpg. Para isso é necessário primeiramente criar um arquivo de configuração para utilizar o gpg.
$ vim ~/.gnupg/gpg.conf
Adicione o seguinte código ao arquivo:
personal-digest-preferences SHA256
cert-digest-algo SHA256
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
E gere a chave:
$ gpg --gen-key
Siga as intruções para a criação da chave e guarde estas informações.
A chave gerada deve ser adicionada ao arquivo changelog dentro da pasta debian/ do nosso projeto.
ejchecker (0.1-1) unstable; urgency=medium
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
-- Jonathan Rufino <jonathan.rufinotkd@gmail.com> Tue, 28 Jun 2016 21:58:49 -0300
O arquivo control é principal arquivo a ser alterado, pois é neste arquivos que colocaremos diversas informações, algumas destas já foram preenchidas quando a pasta debian/ foi gerada como pode ser visto à seguir:
Source: ejchecker
Section: unknown
Priority: optional
Maintainer: Jonathan Rufino <jonathan@unknown>
Build-Depends: debhelper (>=9)
Standards-Version: 3.9.6
Homepage: <insert the upstream URL, if relevant>
#Vcs-Git: git://anonscm.debian.org/collab-maint/ejchecker.git
#Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/ejchecker.git
Package: ejchecker
Architecture: all
Depends: ${misc:Depends}
Description: <insert up to 60 chars description>
<insert long description, indented with spaces>
Já que a única dependência deste módulo é o python, esta foi adicionada ao arquivo, juntamente com as outras devidas informações, obtendo assim o seguinte arquivo:
Source: ejchecker
Section: unknown
Priority: optional
Maintainer: Jonathan Rufino <jonathan.rufinotkd@gmail.com>
Build-Depends: debhelper (>=9)
Standards-Version: 3.9.6
Homepage: https://gitlab.com/ejudge/ejtools
Package: ejchecker
Architecture: all
Depends: ${misc:Depends}, ${shlibs:Depends}, ${python:Depends}
Description: Script para correção de soluções de competição.
O ejtools é um conjunto de ferramentas para a automação de provas e competições de programação.
O projeto é composto de 7 módulos, onde apenas um (core) não é uma ferramenta:
*checker: script para a correção automática das soluções propostas;
*client: programa para o envio de soluções ao servidor;
*core: biblioteca estática com funcionalidades comuns;
*problems: scripts para a formatação e instalação de problemas;
*scoreboard: programa que representa o placar da competição;
*server: servidor que recebe as soluções propostas via rede;
*users: scripts para o cadastro de usuários.
Com o arquivo control configurado, já podemos construir o pacote:
$ cd ejchecker-0.1/
$ debuild
Durante o processo será solicitada a senha da chave criada anteriormente, informe-a e aguarde. Ao fim, será gerado um arquivo chamado ejchecker_0.1-1_all.deb no diretório acima(mesma pasta onde criamos o arquivo .tar.gz anteriormente).
Para instalar o pacote:
$ cd ..
$ sudo dpkg -i ejchecker_0.1-1_all.deb
Para testar se a ferramenta foi instalada corretamente execute:
$ touch a.cpp
$ ejchecker a.cpp
Localizando arquivos para correcao: Ok!
Compilando o arquivo: Ok!
Validando o gabarito: Falha!
[Erro] Compilation Error (CE)
[Dica] Compile o arquivo manualmente
Se for exibida a mensagem de erro acima, a instalação está correta, o erro se da devido ao conteúdo do arquivo não estar de acordo com a entrada exigida pela ferramenta.
Referências
editarhttps://about.gitlab.com/gitlab-ci/#gitlab-runner
https://media.readthedocs.org/pdf/flake8/latest/flake8.pdf
https://docs.docker.com/docker-hub/