Grupo: Lucas Mattioli e Jonathan Rufino

Gerência de Configuração de Software

editar

Esse 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

editar

O 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

editar

Os 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

editar
Perí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

editar

Configuração

editar

A 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

editar

Para 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

editar

Para 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

editar

Ferramentas Utilizadas

editar

Para 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

editar

Primeiro, 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

editar

https://about.gitlab.com/gitlab-ci/#gitlab-runner
https://media.readthedocs.org/pdf/flake8/latest/flake8.pdf
https://docs.docker.com/docker-hub/