Saltar para o conteúdo

AppRecommender

Fonte: Wikiversidade

Grupo: Gabriel Silva e Luciano Prestes

Projeto da disciplina de Gerência de Configuração de Software.

"O AppRecommender é um projeto que provê soluções para a recomendação de aplicações no mundo GNU/Linux"[1]. Atualmente o AppRecommender funciona apenas para distribuições Debian, onde suas soluções para recomendação de pacotes é caracterizada em 3 tipos de estratégias de recomendação, sendo elas:

  • Baseada em conteúdo: recomenda pacotes semelhantes aos pacotes instalados pelo usuário, utilizando as debtags e as descrições dos pacotes;
  • Colaborativa: recomenda pacotes que foram instalados por usuários com perfil semelhante, utilizando os dados do popcon;
  • Híbrida: recomenda pacotes com algoritmos que manipulam as duas estratégias anteriores.

De modo geral, o AppRecommender coleta informações a respeito dos pacotes atualmente instalados no sistema, oferecendo recomendações com base nas categorias de distribuição, em escolhas de outros usuários com ambientes similares, ou demais características (como por exemplo popularidade e estabilidade).

Repositório do AppRecommender: https://gitlab.com/AppRecommender/AppRecommender/

Repositório utilizado na disciplina para contribuir com o AppRecommender: https://gitlab.com/GCS2016/AppRecommender

Este documento apresenta um plano de Gerência de Configuração de software para o AppRecommender. Através deste, define-se diretrizes e atividades para o controle de versões e configuração do sistema em suporte ao desenvolvimento do projeto.

O AppRecommender é um projeto onde a gerência de configuração de software pode contribuir em diversas áreas, dentre elas, a proposta desse projeto é colaborar com o AppRecomender nos seguintes aspectos:

  • Adicionar máquina virtual com o Vagrant
  • Integração contínua
  • Instalação o AppRecommender para ambiente de usuários comuns
  • Empacotamento Debian
  • Automatização de instalação e configuração do ambiente de desenvolvimento através do Chef

Definições, Acrônimos e Abreviações

[editar | editar código-fonte]

Nas seções seguintes deste documento, define-se um cronograma para as atividades de gerenciamento de configuração, bem como todos os resultados obtidos durante este processo. Inclui-se, portanto, a documentação da configuração e execução das tarefas executadas para alcançar os objetivos propostos.

As sprints do projeto são definidas em Milestones no Repositório, e o Backlog é definido pelo conjunto das Issues mapeadas.

Para melhorar a identificação, as issues são categorizadas por labels (rótulos).

Sprints: https://gitlab.com/GCS2016/AppRecommender/milestones?state=all

Backlog: https://gitlab.com/GCS2016/AppRecommender/issues

Labels: https://gitlab.com/GCS2016/AppRecommender/labels

Ferramentas e Ambiente

[editar | editar código-fonte]
  • Vagrant
  • Shell script
  • GitLab CI
  • Docker
  • Flake8
  • [TODO - ferramentas de empacotamento]

Instalação e configuração

[editar | editar código-fonte]

Para funcionar corretamente o AppRecommender era necessário executar uma sequencia de scripts na ordem correta, o que era trabalhoso tanto para um usuário final quanto para um novo contribuidor. Afim de melhorar a instalação e configuração todos os scripts que faziam esse processo foram acoplados ao código-fonte do AppRecommender, e foi então adicionado flags no binário 'apprec.py', que é o binário do programa AppRecommender, sendo assim, o AppRecommender pode ser instalado e configurado através dos seguintes comandos:

$ cd bin/
$ ./apprec.py --init
$ ./apprec.py --train

Os comandos acima instalam e configuram o AppRecommender no caso de estar em ambiente de desenvolvimento, caso esteja com o AppRecommender instalado esses comandos devem ser executados da seguinte maneira:

$ apprec --init
$ apprec --train

Automatização do Ambiente de Desenvolvimento com Vagrant

[editar | editar código-fonte]

Vagrantfile:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|

  config.vm.box = "debian/jessie64"
  config.vm.box_check_update = false
  config.vm.network :forwarded_port, host: 8080, guest: 8080
  config.vm.provision :shell, path: "vagrant/bootstrap.sh", privileged: false
  config.vm.provider "virtualbox" do |vm|
    vm.memory = 1024
    vm.cpus = 2 
  end 
end

O AppRecommender é configurado na máquina através do script bootstrap.sh, onde o AppRecommender é inicializado e o treinamento do aprendizado de máquina é feito. bootstrap.sh:

#!/bin/bash

echo "Install basic dependencies"
sudo apt-get update
sudo apt-get install vim -y

echo "Install AppRecommender dependencies"
cd /vagrant
./install_dependencies.sh

echo "Prepare AppRecommender data"
cd /vagrant/src/bin
./apprec.py --init
./apprec.py --train

Empacotamento

[editar | editar código-fonte]

O empacotamento não foi realizado na disciplina de Gerência de Configuração de Software, pois foi feito pelo Lucas Moura, um participante do Google Summer of Code, porém como trabalho da disciplina o AppRecommender foi devidamente preparado e configurado o script "setup.py" para que a instalação do AppRecommender pudesse acontecer corretamente, pois o empacotamento também utiliza o script "setup.py" para instalar o sistema. A baixo segue o script "setup.py".

from setuptools import setup, find_packages


setup(
    name='apprecommender',
    description="Package recommender for GNU packages",
    version='0.1',
    url='https://github.com/tassia/AppRecommender',
    author='Tassia Camoes Araujo',
    author_email='tassia@acaia.ca',
    license='GPLv3.txt',
    packages=find_packages(),
    setup_requires=['nose>=1.3', 'mock'],
    test_suite='nose.collector',
    entry_points={
        'console_scripts': [
            'apprec = bin.apprec:main',
        ]
    },
)

Integração Contínua

[editar | editar código-fonte]

O GitLab CI foi escolhido como serviço de integração contínua. Trata-se de um serviço livre e completamente integrado ao GitLab, o que remove a dependência a um serviço externo (como é o caso do Travis) e possibilita a criação e configuração de builds e runners personalizados, que podem até mesmo ser executados em uma infraestrutura própria.

Para configurar a integração contínua em um projeto no GitLab, é necessário ativar a funcionalidade de builds na página de configurações do projeto, na seção Features. Em seguida, basta criar o arquivo .gitlab-ci.yml na raiz do projeto. Este arquivo no formato YAML deve descrever todos os passos necessários durante a execução da build, da instalação das dependências até a execução dos testes.

No caso do AppRecommender, as configurações definidas estão transcritas a seguir.

before_script:
  - ./install_dependencies.sh
  - sudo pip2 install flake8
  - pushd bin
  - ./apprec.py --init
  - ./apprec.py --train
  - popd

test:
  script:
    - flake8 .
    - python setup.py test
    - python setup.py build
    - sudo python setup.py install

Durante o processo de build do AppRecommender, um script SHELL vai instalar as dependências necessárias, e a configuração inicial é realizada através da própria aplicação, executada de dentro do diretório bin. Estes procedimentos são realizados no estágio before_script, que executa antes de cada estágio script definido neste mesmo arquivo. O único estágio script definido neste caso executa os testes, e tenta construir e instalar o projeto através do setuptools.

O script SHELL em questão está descrito a seguir.

apt-get update

apt-get install python python-xapian python-apt python-cluster python-webpy python-simplejson python-numpy apt-xapian-index python-xdg debtags python-pip python-sklearn python-matplotlib python-stemmer -y

update-apt-xapian-index

pip install setuptools

É importante perceber que alguns destes comandos executam tarefas que exigem maiores permissões no sistema. Neste caso, é essencial garantir que a build seja executada com um usuário root (ou com permissões de sudo, desde que os scripts prevejam a sua utilização).

O GitLab possuir diversos tipos de runners, que são mecanismos que definem a maneira em que a build será executada. Dentre eles, existe o suporte à execução da build em um container do Docker, o que garante um usuário root durante a execução, e um ambiente limpo a cada build. Também é possível executar a build em modo SHELL, mas isso garante um ambiente de execução limpo, visto que os comandos são executados diretamente na seção da máquina que hospede o runner.

O Docker foi escolhido como mecanismo de execução de builds para o AppRecommender.

Docker runners

[editar | editar código-fonte]

Utilizando-se o Docker, é possível garantir que a build sempre vai ser executada em um ambiente limpo, visto que a cada execução um container será criado a partir de uma imagem base, que represente o ambiente mínimo necessário para a construção do AppRecommender. Mais precisamente, algo equivalente à imagem python:2.7.

A imagem python:2.7 trata-se de um Debian Jessie com o Python, PIP, e outras ferramentas básicas instaladas. Desta forma, é possível executar todo o processo de build do zero, desde a instalação das dependências.

No entanto, o script de instalação de dependências do AppRecommender executa o update-apt-xapian-index, que pode levar muito tempo, ainda mais em um ambiente limpo, custo cache do APT acabou de ser atualizado pela primeira vez. Executar este comando apenas no processo de build em uma imagem padrão python:2.7 pode tornar o tempo de execução muito alto. Uma possibilidade é criar uma imagem com base em python:2.7 com algumas tarefas previamente realizadas, como por exemplo a atualização do cache do APT, e execução do comando update-apt-xapian-index. É evidente que seria possível construir uma imagem que já possua todas as dependências instaladas, o que tornaria o processo de build ainda mais rápido. No entanto, pode ser interessante testar inclusive o processo de instalação, tornando a integração contínua mais completa.

Para criar uma imagem personalizada com base na python:2.7, é necessário um sistema Linux com suporte a LXC e Docker instalado. Em um sistema Debian like, o Docker pode ser isntalado através do APT.

$ sudo apt-get install docker
ou
$ sudo apt-get install docker.io

Tente executar o comando '$ docker', se o comando não for encontrado execute os seguintes comandos.

$ sudo apt-get install curl
$ curl -sSL https://get.docker.com/ | sh

Em seguida, é necessário baixar a imagem base desejada, e em seguida criar um novo container a partir dela.

$ docker pull python:2.7
$ docker run -t -i python:2.7 /bin/bash

O último comando acima vai abrir um console iterativo no interior do novo container. Dentro do container, já é possível executar os comandos desejados. Neste caso, deseja-se apenas atualizar o cache do APT, instalar o Xapian, e reconstruir seus índices, para que este processo não demore muito durante as builds.

root@288afe7539f3:/# apt-get update
root@288afe7539f3:/# apt-get install apt-xapian-index
root@288afe7539f3:/# update-apt-xapian-index

Deve-se atentar que o shell do container exibe o usuário root e o ID do container recém criado. Este é o valor que deve ser utilizado para salvar as alterações como uma nova imagem. Antes de criar a nova imagem, é necessário possuir algum repositório para a compartilhar. Primeiro, deve ser criado um novo repositório no Docker Hub, para em seguida criar a nova imagem através do comando commit, especificando o ID do container criado anteriormente, e o nome do repositório recém criado,

$ docker commit -m "Updating Xapian indexes" -a "John Doe" 288afe7539f3 johndoe/apprecommender:base

O comando acima vai compartilhar a imagem com a tag base. Agora esta imagem pode ser referenciada como johndoe/apprecommender:base. Para que o GitLab CI use esta imagem durante a build, adicione a seguinte linha no início do arquivo .gitlab-ci.yml.

image: johndoe/apprecommender:base

Criando um novo runner

[editar | editar código-fonte]

Em uma máquina que tenha a acesso a internet e disponibilidade computacional para a execução das builds, instale o gitlab-ci-multi-runner

$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
$ [sudo] apt-get install gitlab-ci-multi-runner

Em seguida, crie um novo runner através da ferramenta de linhas de comando do GitLab. Algumas informações serão solicitadas, como a URL do mecanismo de integração contínua, e o token do projeto. Estas informações devem ser definidas de acordo com as configurações dos runners seu projeto, acessadas em Settings -> Runners. Quando questionado sobre o mecanismo de execução, escolha docker, e defina a imagem adequada.

$ [sudo] gitlab-ci-multi-runner register
> Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci )
https://gitlab.com/ci
> Please enter the gitlab-ci token for this runner
<your token>
> Please enter the gitlab-ci description for this runner
runner-name
> Registering runner... succeeded
> Please enter the executor: shell, docker, docker-ssh, ssh?
docker
> Please enter the Docker image (eg. ruby:2.1):
gabrielssilva/apprecommender:base
> Runner registered successfully. Feel free to start it, but if it's

Caso deseje executar o runner como "shell" ao invés de "docker", basta digitar a opção "docker" quando o registro solictitar "Please enter the executor"

O token do projeto já é suficiente para conectar o runner ao projeto. Portanto, logo após o registro, ele já pode ser visto na lista de runners cadastrados, e usado em um novo processo de build. Para executar uma build localmente, execute o comando abaixo no diretório que contenha o .gitlab-ci.yml (considerando que exista um job chamado test definido no arquivo YAML).

$ [sudo] gitlab-ci-multi-runner exec docker test
  1. https://github.com/tassia/AppRecommender/wiki