PET
Autores: Tiago R. Assunção e Wesley Araújo
Visão geral
editarEste projeto de Gerência de Configuração foi desenvolvido como pré requisito parcial para a disciplina de GCS(Gerência de Configuração de Software) da Faculdade UnB-Gama(FGA). De acordo com o RUP, o Plano de Gerenciamento de Configuração (CM) descreve todas as atividades do Gerenciamento de Controle de Configuração que serão executadas durante o ciclo de vida do produto ou do projeto. Este presente plano apresentará os pontos envolvendo gerência de configuração no projeto Package Entropy Tracker(PET), que pode ser acessado neste link, que faz o Tracking dos pacotes que estão sendo desenvolvidos pelos Debian Developers(DD's).
O PET é dividido em oito módulos:
- bts
- classifier
- models
- perlre
- sql
- update
- vcs
- watch
Este software busca nos repositórios estabelecidos todos os pacotes desenvolvidos para o Debian. Ele possibilita a visualização das versões dos pacotes, branchs, diferenças entre elas, os repositórios dos UpStreams, quantidade de bugs em cada pacote, entre outros pontos. Além disso, todos os pacotes são divididos por time de desenvolvimento, por exemplo:
- Time de Perl
- Time de Java
- Time de Ruby
Assim, possuem vários outros times que desenvolvem os pacotes.
Atualmente, o processo de instalação pode ser feito através do Vagrant, que já está configurado ou instalando as dependências diretamente em sua máquina.
O repositório atual pode ser encontrado no GitHub-PET
Repositórios
editarEmpacotamento pyramid_chameleon: https://github.com/gcs-fga/pyramid-chameleon_packing
Empacotamento debian: https://github.com/gcs-fga/pet
Vagrant usando puppet: https://github.com/gcs-fga/pet_vagrant_puppet
Empacotamento pip: https://github.com/gcs-fga/pet_pip_packing
Propósito
editarIremos descrever aqui os pontos necessários quanto a Gerecia de Configuração de Software que será aplicado no PET, bem como algumas diretrizes para a normatização de que se procederá para aplicar os pontos propostos.
Escopo
editar- Empacotar o PET em um arquivo .deb.
- Automatizar o deploy no ambiente de produção usando uma receita chef
Definições, Acrônimos e Abreviações
editarPET - Package Entropy Tracker
RUP - Rational Unified Process
Debian - Sistema Operacional de distribuição Linux que segue a licença GNU.
Cronograma
editarDefinição das Sprints
editarSprint | Data | Atividade |
---|---|---|
01 | 27/04 - 11/05 | Início do Processo de Empacotamento do PET |
02 | 12/05 - 25/05 | Finalização do Processo de Empacotamento do PET |
03 | 26/05 - 15/06 | Vagrant usando puppet
Empacotamento pip na Pypi |
Definição das Milestones
editar- 27/06 - Definição do Plano de SCM
- 01/06 - Ponto de Controle
- 22/06 - Entrega Final do Trabalho
Ferramentas Utilizadas
editarEmpacotadores Debian
editar- dpkg
- dh_make
- debuid
Manipulador de pacotes debian .deb. Para utilização do dpkg acessar https://debian-handbook.info/browse/pt-BR/stable/sect.manipulating-packages-with-dpkg.html
Vagrant
editarVagrant é uma ferramenta de virtualização de ambientes que, aliado ao Virtual Box da Oracle, permite criar ambientes de desenvolvimento sem a necessidade de configuração direta no computador, trazendo vantagens de, por exemplo, ter múltiplos ambientes de desenvolvimento no mesmo computador.
Resultados
editarEmpacotamento Pyramid-Chameleon
editarO pacote pyramid-chameleon só é possível instalar por meio do pip. Como o PET utiliza essa dependência, porém não consegue acessar pelo pip, é necessário empacotar o pyramid-chameleon também para .deb. Todas as instruções do empacotamento geral estão na subceção "Ambiente Necessário para o Empacotamento", aqui da Seção de resultado, por isso, nesta subceção só será tratado de como está configurado os arquivos principais da pasta debian para o pyramid_chameleon.
Para que seja possível a instalação do pacote, é preciso ter duas dependências que são instaladas com o APT:
- python-pyramid
- python-chameleon
Processo de Empacotamento
editarPrimeiro, é necessário fazer o clone da source do pyramid_chameleon
# Clona o repositório
git clone https://github.com/gcs-fga/pyramid-chameleon_packing.git
# Sincroniza as branchs
git fetch
# Altera a branch para a de empacotamento
git checkout packing-debian
Renomear o diretório do repositório local
mv pyramid-chameleon_packing pyramid-chameleon-0.1
Após isso, é preciso criar um .tar.gz do diretório, porém, como no nosso repositório já existe uma pasta debian, pode-se ignora-la pelo comando tar:
tar -zcvf pyramid-chameleon-0.1.tar.gz pyramid-chameleon-0.1/ --exclude=/debian
Arquivo Control
editarO arquivo control precisa das dependências do python. Como esse pacote está apenas para o python 2, então não foi adicionado o python3.
Source: pyramid-chameleon
Section: unknown
Priority: optional
Maintainer: Tiago Assuncao <tiago@sof2u.com>
Wesley Araujo <wesley.sickert@gmail.com>
Build-Depends: debhelper (>= 9), python (>= 2.6.6-3~)
X-Python-Version: >= 2.6
Standards-Version: 3.9.5
Homepage: <insert the upstream URL, if relevant>
#Vcs-Git: git://anonscm.debian.org/collab-maint/pyramid-chameleon.git
#Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/pyramid-chameleon.git;a=summary
Package: pyramid-chameleon
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}
Description: pyramid-chameleon to python2
pyramid_chameleon is a set of bindings that make templates written for the Cham eleon templating system work under the Pyramid web framework
Status API Training Shop Blog About
Criando o .deb
editarApós a preparação do arquivo control, o dh_make é executado no diretório do projeto, fora do /debian. O dh_make não irá sobrescrever o diretório /debian já criado.
dh_make -f ../pyramid-chameleon-0.1.tar.gz
Depois de executado o dh_make, o build é criado através do debuild.
debuild -us -uc
Quando o debuild é executado, o nosso pacote .deb estará fora do nosso diretório do projeto, o diretório anterior.
Ambiente Necessário para o Empacotamento
editarIniciando o processo de empacotamento, é necessário instalar duas ferramentas que utilizadas para gerar a primeira estrutura do pacote e outro para fazer a build do pacote montado. Eles são o dh_make e o debuild.
O primeiro pacote é o dh_make, que gera um template dos arquivos necessários para o empacotamento. Ele pode ser instalado pelo repositório do debian:
$ sudo apt-get install dh-make
Após, o pacote necessário para fazer a build do pacote deve ser instalado:
$ sudo apt-get install build-essential
Pronto. Seu ambiente está pronto para gerar os pacotes básicos do debian.
Elaboração do Script de Empacotamento
editarSeguirá aqui um roteiro da elaboração do pacote utilizando o repositório do PET para GCS: https://github.com/gcs-fga/pet.
O primeiro passo para criar nosso pacote é obter o código do Upstream. Assim, foi feito um clone nas nossas máquinas dos mantenedores:
$ git clone https://anonscm.debian.org/cgit/pet/pet3.git/
Após, faz-se necessário para o dh_make que o diretório do empacotamento esteja no formato contento a versão do pacote, da seguinte maneira: pet-0.1/.
Criação da estrutura do empacotamento
editarAssim, a pasta pet foi renomeada:
$ mv pet pet-0.1
Além disso, o dh utiliza de um aquivo comprimido para executar o empacotamento. Dessa maneira, o seguinte comando foi utilizado para transformar o diretório em um arquivo .tar.gz:
$ tar -zcvf pet-0.1.tar.gz pet-0.1/
Assim, a primeira estrutura contendo templates pode ser criada utilizando o dh(se faz necessário entrar na pasta pet-0.1 e rodar o dh_make lá de dentro passando como argumento o arquivo .tar.gz):
$ dh_make -f ../pet-0.1.tar.gz
Dessa maneira, a pasta debian/ é criada. Ela armazena todos os arquivos necessários para fazer o empacotamento. São criados vários arquivos exemplos com a extensão .ex e .EX. Além deles, outros arquivos como watch são desnecessários. Assim, todos esses arquivos foram apagados a partir da raiz do diretório:
$ cd debian/
$ rm *.ex
$ rm *.EX
$ rm watch
$ cd ..
Dentro do arquivo rules, existe vários conteúdos desnecessários que foram apagados. E apenas o código a seguir permaneceu:
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
Criação da secret key
editarPara a autenticação do pacote, é necessário criar um par de chaves assimétricas no computador de quem gera o pacote. Para isso, usa-se a ferramenta gpg:
Primeiramente, cria-se um arquivo na home com alguns parâmetros pessoais para a utilização do gpg. Um exemplo pode ser o arquivo criado a seguir, que pode ser visto também no site https://keyring.debian.org/creating-key.html:
$ mkdir -p ~/.gnupg/
$ vim ~/.gnupg/gpg.conf
E adicione o seguinte conteúdo no arquivo gpg.conf:
personal-digest-preferences SHA256
cert-digest-algo SHA256
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
Agora pode-se gerar a chave através do comando:
$ gpg --gen-key
Ao criar a chave, ele dará 4 opções de tipo de chaves assimétricas. A mais comum no dia de hoje é a RSA. Pode-se escolher a primeira opção que utiliza a assinatura digital com RSA e o par de chaves com RSA, a opção 1.
Após, é indagado sobre em quanto tempo sua chave deve expirar, pode escolher quanto tempo desejar. Assim, ele questiona qual o nome do quem está gerando a chave, bem como seu email. Esse par de campos será utilizado como identificador da sua chave.
Será solicitado uma palavra passe para você utilizar a chave(Não esqueça essa palavra passe).
Logo após, o algorítimo que faz a geração da chave aleatória necessita de uma fonte de entropia para gerar os números primos que compõem o RSA. O sistema operacional irá utilizar as fontes de entropia do seu computador, que são as entradas do mouse e do teclado, além dos movimentos da pinça que posiciona a agulha do disco rígido. Depois de algum tempo, que todos os bytes aleatórios forem gerados, a sua chave será criada.
Registro da Chave no Changelog
editarNo final da geração da chave, uma ID da chave será indicada na tela. Ela é composta pelo nome e email citados pelo gerador da chave no seguinte formato:
Test User <test@example.org>
A final, pra que server essa chave?
Ela deve ser adicionada no arquivo de Changelog com as mudanças que foram feitas no empacotamento. E a chave deve ser adicionada no Initial Release, como o exemplo a seguir:
pet (0.1-1) unstable; urgency=low
* Initial release (Closes: #nnnn) <nnnn is the bug number of your ITP>
-- Tiago Assuncao <tiago@sof2u.com> Tue, 31 May 2016 21:44:08 -0300
Edição do Control
editarO control é o principal arquivo do empacotamento, onde são colocadas informações tais como o nome do pacote, versão, importância, arquitetura dos sistemas(32, 64, etc), pacotes necessários para a build da instalação e pacotes para a sua execução. O arquivo control vem com um template gerado pelo dh_make quem vem a seguir:
1 Source: package_name
2 Section: unknown
3 Priority: extra
4 Maintainer: User Test <user_test@debian.org>
5 Build-Depends: debhelper (>=9)
6 Standards-Version: 3.9.4
7 Homepage: <insert the upstream URL, if relevant>
8
9 Package: package_name
10 Architecture: any
11 Depends: ${shlibs:Depends}, ${misc:Depends}
12 Description: <insert up to 60 chars description>
13 <insert long description, indented with spaces>
O pacote do PET tem algumas propriedades específicas. A descrição foi utilizada por padrão a do pet.
E o ponto mais crítico é adicionar as dependências do projeto. Dentro do PET, foram identificadas todas as dependências de execução do software. Os seguintes pacotes foram identificados:
- python,
- postgresql-9.4-debversion,
- postgresql-9.4,
- wget,
- python-paste,
- python-argparse,
- python-debian,
- python-debianbts,
- python-inotifyx,
- python-psycopg2,
- python-pyramid,
- python-sqlalchemy,
- python-subversion
Além das dependências do python em geral, pois, o PET é escrito nesta linguagem, que pode ser entendido como: ${python:Depends}
Para as dependências de Build foram identificados os seguintes pacotes:
- debhelper (>= 8.0.0),
- postgresql-9.4
Dessa forma, o arquivo control se encontra desta maneira até o momento:
Source: pet
Section: base
Maintainer: Tiago Assuncao <tiago@sof2u.com>
Wesley Araujo <wesley.sickert@gmail.com>
Build-Depends: debhelper (>= 8.0.0), postgresql-9.4
Standards-Version: 3.9.4
Priority: optional
Package: pet
# Version: 0.1
Architecture: any
Depends: ${shlibs:Depends}, ${python:Depends}, ${misc:Depends}, postgresql-9.4-debversion, postgresql-9.4, wget, python-argparse, python-debian, python-debianbts, python-inotifyx, python-paste, python-psycopg2, python-pyramid, python-sqlalchemy, python-subversion
Description: PET - Package Entropy Tracker
PET is a collection of scripts that gather information about your (or your group's) packages. It allows you to see in a bird's eye view the health of hundreds of packages, instantly realizing where work is needed.
Criação do Pacote
editarPara criar o pacote, a segunda ferramenta é utlizada: debuild. Este passo é bem simples. Basta rodar o comando e ele irá compilar o pacote dentro de um .deb e colocá-lo no mesmo diretório que o arquivo .tar.gz foi criado. Dessa maneira:
$ debuild
Dessa maneira, o pacote pode ser distribuído e instalado. Um exemplo de instalação vem a seguir:
$ cd ..
$ sudo dpkg -i pet_0.1-1_i386.deb
Assim o pacote será instalado, para mais detalhes, ir para a Subseção de instalação.
Como dito anteriormente, o source do pacote pode ser encontrado no seguinte repositório: https://github.com/gcs-fga/pet/
Instalação do PET via pacote Debian
editarAntes da instalação do pacote PET, é necessário instalar o pacote do pyramid_chamaleon.
$ sudo dpkg -i pyramid-chameleon
Depois, a instalação do PET
$ sudo dpkg -i pet
Utilização do PET
editarQuando instalado, o PET é executado por meio do comando pet, no qual permite atualizar o repositório local, pegar os pacotes do repositorio atualizado usando o nome do pacote como argumento e rodar o servidor. Para informações da utilização do pet, utuilizar a opção -h ou --help:
# Atualiza o repositório
$ pet -u -r
# Pega pacote(s)
$ update-package nome_pacotes
# Atualiza os pacotes
$ pet -u -p
# Roda o PET
$ pet -s
Observações:
Caso o comando pet não possa ser encontrado, configurar para que a variável PATH tenha as paths /usr/bin/pet para o comando update-package e /usr/bin/pet/shell para o comando pet.
A opção -h detalha as opções e argumentos e também mostra como rodar o pet em um mini-tutorial.
Criação dos Parâmetros com o Vagrant
editarVagrant usando Puppet
editarO Puppet foi utilizado como ferramenta de gerência de configuração para a instalação de todas as dependências na virtualização do vagrant, apesar do Chef estar disponível antes por outra equipe.
Configuração do Vagrantfile
editarO Vagrantfile foi configurado para que o ambiente de desenvolvimento contesse o puppet já instalado, sendo utilizado o shell que está na subseção de instalação do puppet.
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "debian/jessie64"
config.vm.provider "virtualbox" do |vm, override|
override.vm.network 'forwarded_port', guest: "8080" , host: "4567"
end
# puppet-bootstrap
config.vm.provision "shell", path: "scripts/debian.sh"
config.vm.provision "puppet" do |puppet|
puppet.manifest_file = "site.pp"
puppet.manifests_path = "manifests"
end
end
Execução do Shell de Instalação do Puppet
editarEsta parte é importante para que seja executado o shell de instalação, que é detalhado na subseção Instalação do Puppet, utilizando-se do provisioner "shell" do Vagrant.
# puppet-bootstrap
config.vm.provision "shell", path: "scripts/debian.sh"
Configuração do puppet para o Manifest
editarCom o provisioner "puppet" disponível no Vagrant, o arquivo manifest, que conterá as dependências, é criado e também o caminho no qual os manifests estarão.
config.vm.provision "puppet" do |puppet|
puppet.manifest_file = "site.pp"
puppet.manifests_path = "manifests"
end
Instalação do Puppet
editarA instalação do Puppet é feita pelo script "debian.sh", que foi referenciado no Vagrantfile no provisioner "shell".
#!/usr/bin/env sh
echo "Initial apt-get update..."
apt-get update >/dev/null
REPO_DEB_URL="http://apt.puppetlabs.com/puppetlabs-release-jessie.deb"
echo "Installing wget..."
apt-get --yes install wget >/dev/null
echo "Configuring PuppetLabs repo..."
repo_deb_path=$(mktemp)
wget --output-document="${repo_deb_path}" "${REPO_DEB_URL}" 2>/dev/null
dpkg -i "${repo_deb_path}" >/dev/null
rm "${repo_deb_path}"
apt-get update >/dev/null
echo "Installing Puppet..."
DEBIAN_FRONTEND=noninteractive apt-get -y install puppet >/dev/null
echo "Puppet installed!"
Atualizando apt-get e instalando o wget
editarAntes de tudo, o apt-get é atualizado para que seja mais recente e os pacotes também. Logo depois é criada uma variável de ambiente com o nome REPO_DEB_URL que contém o pacote Debian para o Puppet. Então é utilizado o apt-get para a instalação do wget que será usado posteriormente.
echo "Initial apt-get update..."
apt-get update >/dev/null
REPO_DEB_URL="http://apt.puppetlabs.com/puppetlabs-release-jessie.deb"
echo "Installing wget..."
apt-get --yes install wget >/dev/null
Configurando o Repositório do PuppetLabs
editarÉ criada um diretório temporário e armazenado o path na variável repo_deb_path.
Utiliza-se o comando --output-document do wget para adicionar os parâmetros do path onde será armazenado o repositório e a url de onde virá, que está na variável de ambiente REPO_DEB_URL. Depois disso o arquivo .deb é desempacotado com o dpkg e então a path temporária é removida. O apt-get é atualizado novamente.
echo "Configuring PuppetLabs repo..."
repo_deb_path=$(mktemp)
wget --output-document="${repo_deb_path}" "${REPO_DEB_URL}" 2>/dev/null
dpkg -i "${repo_deb_path}" >/dev/null
rm "${repo_deb_path}"
apt-get update >/dev/null
Conclusão da Instalação
editarFinalmente é instalado o Puppet. É importante que a instalação por meio do apt-get não seja interativo [1]
echo "Installing Puppet..."
DEBIAN_FRONTEND=noninteractive apt-get -y install puppet >/dev/null
echo "Puppet installed!"
Configuração do Manifest
editarApós a instalação correta do Puppet com o Vagrant, o nosso manifest "site.pp" é configurado com as dependências necessárias. É importante notar que os pacotes que não são instalados com o apt-get devem ter seu comando explicitado, como é o caso do pyramid_chameleon, que é executado pelo pip. Um usuário "pet" é criado e o arquivo postgresql.conf é substituído por outro que está na path manifests/files, o mesmo ocorre com o pg_hba.conf. Depois o um banco é criado no postgres e populado com as devidas configurações que o PET necessita.
package { [
'python',
'vim',
'vagrant',
'python-pip',
'postgresql-9.4',
'postgresql-9.4-debversion',
'python-argparse',
'python-debian',
'python-debianbts',
'python-inotifyx',
'python-paste',
'python-psycopg2',
'python-pyramid',
'python-sqlalchemy',
'python-subversion',
]:
ensure => present,
}
package { 'pyramid_chameleon':
provider => pip,
ensure =>present,
}
include user
class user{
user { 'pet':
ensure => present,
shell => '/bin/bash',
home => '/home/pet',
}
file { 'postgresql conf':
path => '/etc/postgresql/9.4/main/postgresql.conf',
ensure => file,
content => template("/tmp/vagrant-puppet-4/manifests/files/postgresql.conf"),
}
file { 'pg_hba conf':
path => '/etc/postgresql/9.4/main/pg_hba.conf',
ensure => file,
content => template("/tmp/vagrant-puppet-4/manifests/files/pg_hba.conf"),
}
exec { 'psql create user':
user => "postgres",
command => "/usr/bin/createuser pet",
path => "/home/pet",
unless => "/usr/bin/psql postgres -tAc \"SELECT 1 FROM pg_roles WHERE rolname='pet'\" | /bin/grep -q 1"
}
exec { 'create db pet':
user => "postgres",
command => "/usr/bin/createdb -O pet pet",
path => "/home/pet",
unless => "/usr/bin/psql -lqt | /usr/bin/cut -d \| -f 1 | /bin/grep -qw pet",
}
exec { 'implements deb version':
user => "postgres",
command => "/usr/bin/psql pet < /usr/share/postgresql/9.4/contrib/debversion.sql",
path => "/home/pet",
}
file { 'hosts file':
path => "/etc/hosts",
ensure => file,
content => template("/tmp/vagrant-puppet-4/manifests/files/hosts"),
}
service {"postgresql":
ensure => running,
enable => true,
hasrestart => true,
}
exec { "creating tables":
command => "/usr/bin/python /vagrant/pet-update -c -nc",
user => "pet",
unless => "/usr/bin/psql pet -tAc \"SELECT 1 FROM team\" | /bin/grep -q 1",
path => "/",
}
exec{ "insert a team on bd":
command => "/usr/bin/psql pet --command \"INSERT INTO team (name, maintainer, url) VALUES ('pkg-perl', 'Debian Perl Group <pkg-perl-maintainers@lists.alioth.debian.org>', 'http://pkg-perl.alioth.debian.org/');\"",
user => "pet",
unless => "/usr/bin/psql pet -tAc \"SELECT * FROM team WHERE name='pkg-perl'\" | /bin/grep -q 'pkg-perl'",
}
exec{ "database insert repository table":
command => "/usr/bin/psql pet --command \"INSERT INTO repository (name, type, root, web_root, team_id) VALUES ('git','git','https://pet.alioth.debian.org/pet2-data/pkg-perl/git-pkg-perl-packages.json','http://anonscm.debian.org/gitweb/?p=pkg-perl/packages', 1);\"",
user => "pet",
unless => "/usr/bin/psql pet -tAc \"SELECT * FROM repository WHERE name='git'\" | /bin/grep -q 'git'",
}
exec{ "database insert package table":
command => "/usr/bin/psql pet --command \"INSERT INTO package (name, repository_id) VALUES ('clive', 1);\"",
user => "pet",
unless => "/usr/bin/psql pet -tAc \"SELECT * FROM package WHERE name='clive'\" | /bin/grep -q 'clive'"
}
exec{ "database insert archive table":
command => "/usr/bin/psql pet --command \"INSERT INTO archive (name, url, web_root) VALUES ('debian', 'http://cdn.debian.net/debian', 'http://packages.qa.debian.org/');\"",
user => "pet",
unless => "/usr/bin/psql pet -tAc \"SELECT * FROM archive WHERE name='debian'\" | /bin/grep -q 'debian'",
}
exec{ "database insert suite table":
command => "/usr/bin/psql pet --command \"INSERT INTO suite (archive_id, name) VALUES (1, 'unstable');\"",
user => "pet",
unless => "/usr/bin/psql pet -tAc \"SELECT * FROM suite WHERE name='unstable'\" | /bin/grep -q 'unstable'",
}
}
Empacotamento Pip
editarO pip é a ferramenta de controle de pacotes padrão dos pacotes python. Qualquer desenvolvedor pode desenvolver seus pacotes e deixá-los disponíveis para download e instalação. Eles são todos controlados pela Pypi https://pypi.python.org/pypi.
De ante mão, nosso pacote encontra-se disponível na seguinte url: https://pypi.python.org/pypi/pet-debian/
O processo de instalação seguido foi o estabelecido no site oficial do python: https://packaging.python.org/en/latest/distributing/.
Bem, para a criação do pacote, é necessário que haja uma estrutura correta dos arquivos e da criação de alguns arquivos, como: setup.py, MANIFESTS.in, setup.cfg, entre outros que serão listados a seguir:
Estrutura de diretórios
editarHá a necessidade que uma estrutura de diretórios seja seguida para o setup.py consiga fazer todo o empacotamento de maneira correta. Primeiramente, todos os arquivos de configuração do pypi devem ser colocados dentro da pasta raiz. E tudo o que será utilizado no software deve ser implementado dentro da sub pasta com mesmo nome do projeto, contendo o arquivo __init__.py do projeto.
funniest/
funniest/
__init__.py
app1/
models.py
views.py
app2/
models.py
update.py
server.py
COPYING
README.rst
README.md
MANIFEST.in
setup.py
setup.cfg
O projeto do pet ficou com a seguinte estrutura de diretórios:
.
├── [4.0K] build/
│ ├── [4.0K] bdist.linux-i686/
│ └── [4.0K] lib.linux-i686-2.7/
│ └── [4.0K] pet/
│ ├── [4.0K] web/
│ │ ├── [1.5K] __init__.py
│ │ └── [3.1K] views.py
│ ├── [ 0] asdfas.py
│ ├── [5.2K] bts.py
│ ├── [6.6K] classifier.py
│ ├── [1.5K] exceptions.py
│ ├── [1.2K] __init__.py
│ ├── [7.5K] models.py
│ ├── [4.0K] perlre.py
│ ├── [1.4K] pet_update.py
│ ├── [ 122] serve.py
│ ├── [ 11K] sql.py
│ ├── [ 16K] update.py
│ ├── [ 13K] vcs.py
│ └── [ 11K] watch.py
├── [4.0K] cookbooks/
│ └── [4.0K] pet/
│ ├── [4.0K] files/
│ │ ├── [ 248] hosts
│ │ ├── [4.6K] pg_hba.conf
│ │ └── [ 21K] postgresql.conf
│ └── [4.0K] recipes/
│ └── [3.4K] default.rb
├── [4.0K] dist/
│ ├── [ 34K] pet_debian-1.2.72-py2-none-any.whl
│ └── [ 28K] pet-debian-1.2.72.tar.gz
├── [4.0K] doc/
│ └── [2.8K] debconf11-pet-bof.txt
├── [ 12K] log/
│ ├── [ 33K] pet_debian-1.2.0-py2-none-any.whl
│ ├── [ 24K] pet-debian-1.2.0.tar.gz
├── [4.0K] pet/
│ ├── [4.0K] __pycache__/
│ │ ├── [ 492] __init__.cpython-34.pyc
│ │ └── [9.3K] models.cpython-34.pyc
│ ├── [4.0K] web/
│ │ ├── [4.0K] __pycache__/
│ │ │ └── [1.2K] __init__.cpython-34.pyc
│ │ ├── [4.0K] static/
│ │ │ ├── [3.7K] default.css
│ │ │ └── [1.4K] overview.js
│ │ ├── [4.0K] templates/
│ │ │ ├── [ 612] changelog.pt
│ │ │ └── [3.9K] overview.pt
│ │ ├── [1.5K] __init__.py
│ │ └── [3.1K] views.py
│ ├── [5.2K] bts.py
│ ├── [6.6K] classifier.py
│ ├── [1.5K] exceptions.py
│ ├── [1.2K] __init__.py
│ ├── [7.5K] models.py
│ ├── [4.0K] perlre.py
│ ├── [1.4K] pet_update.py*
│ ├── [4.0K] README.rst
│ ├── [ 122] serve.py
│ ├── [ 11K] sql.py
│ ├── [ 16K] update.py
│ ├── [ 13K] vcs.py
│ └── [ 11K] watch.py
├── [4.0K] pet_debian.egg-info/
│ ├── [ 1] dependency_links.txt
│ ├── [ 90] entry_points.txt
│ ├── [5.8K] PKG-INFO
│ ├── [ 29] requires.txt
│ ├── [ 580] SOURCES.txt
│ └── [ 4] top_level.txt
├── [4.0K] __pycache__/
│ ├── [ 414] serve.cpython-34.pyc
│ └── [ 267] teste.cpython-34.pyc
├── [ 74] COPYING
├── [2.6K] Dockerfile
├── [ 161] Makefile
├── [ 79] MANIFEST.in
├── [3.3K] pet-cat-file*
├── [2.9K] petd*
├── [ 873] pet.wsgi
├── [4.0K] README.md
├── [4.0K] README.rst
├── [ 300] serve.py
├── [ 44] setup.cfg
├── [5.4K] setup-pkg-go
├── [3.3K] setup.py
├── [1.1K] TODO
├── [1.2K] update-archive*
├── [1.0K] update-bts*
├── [1.3K] update-package*
├── [1.6K] update-repository*
├── [1.5K] update-watch*
└── [3.3K] Vagrantfile
20 directories, 213 files
Configuração do setup.py
editarO arquivo setup.py é o principal arquivo do empacotamento, e sua configuração será descrita nas variáveis que tem que ser configuradas a seguir:
Imports
editarPara compilar o setup, são necessários alguns imports. O primeiro deles é o próprio método de setup, que receberá todos os parâmetros de configuração. Outro módulo é o find_packages, que irá fazer uma busca automática dos pacotes que o seu depende. Por fim, dois módulos de configuração de arquivos, o open e o path, para encontrar algum caminho no sistema e para abrir o README.rst.
from setuptools import setup, find_packages
from codecs import open
from os import path
Descrição longa
editarPara utilizar posteriormente, é necessário declarar algumas variáveis úteis. A primeira delas é o here, que captura, utilizando o path, o diretório absoluto do arquivo setup.py. Além disso, guardamos a descrição longa do pacote oriunda do README.rst através do open, utilizando o path.
here = path.abspath(path.dirname(__file__))
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = f.read()
Dados iniciais
editarPara identificar o pacote com nome, versão, descrição curta, url do source, nome e email do autor e a licença devem ser passados nas seguintes variáveis:
name='pet-debian',
version='1.2.71',
description='PET is a collection of scripts that gather informatio about your packages',
long_description=long_description,
url='https://github.com/PET-UnB/pet',
author='Tiago Assuncao',
author_email='tiago@sof2u.com',
license='GPL3',
Classificadores
editarOs classificadores são parâmetros que servem para facilitar que os usuários encontrem pacotes por categorias. Você deve sempre colocar as categorias condizentes com o seu pacote. No link a seguir, estão listadas todas as categorias existentes: https://pypi.python.org/pypi?%3Aaction=list_classifiers.
Segue a baixo um exemplo de lista de classificadores:
classifiers=[
# How mature is this project? Common values are
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 3 - Alpha',
# Indicate who your project is intended for
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',
# Pick your license as you wish (should match "license" above)
'License :: OSI Approved :: MIT License',
# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
],
Palavras chave e pacotes
editarPara facilidade de indexação da Pypi, eles utilizam um mecanismo de palavras chave. Essas podem ser passadas em uma variável chamada keywords. Além disso, pode-se setar a variável packages, utilizando o find_packages citado no início. O código ilustra o funcionamento:
keywords='sample setuptools development',
packages=find_packages(),
Dependências
editarAlém do find_packages, é possível especificar quais outros pacotes são necessários para instalar. A variável install_requires é responsável por isso:
install_requires=[
'pyramid_chameleon',
'SQLAlchemy',
],
Pontos de Entrada
editarOs pontos de entrada são as interfaces que você irá configurar para que o sistema operacional do usuários se comunique com seu software empacotado através de comandos. Para que funcione, deve-se passar o nome desejado do comando seguido do arquivo e o módulo desejado. A sintaxe esperada é a seguinte:
nome_do_comando = nome_do_arquivo:nome_do_metodo
Neste software, nós utilizamos dois pontos de entrada. O primeiro com link para iniciar o servidor e o segundo para atualizar o sistema. Os pontos de entrada do pet podem ser visualizados abaixo.
entry_points={
'console_scripts': [
'pet_serve=pet.serve:pet_serve',
'pet_update=pet.pet_update:pet_update',
],
},
Dessa maneira, o setup.py do pet como inteiro ficou da seguinte maneira:
# Always prefer setuptools over distutils
from setuptools import setup, find_packages
# To use a consistent encoding
from codecs import open
from os import path
here = path.abspath(path.dirname(__file__))
# Get the long description from the README file
with open(path.join(here, 'README.rst'), encoding='utf-8') as f:
long_description = f.read()
setup(
name='pet-debian',
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version='1.2.73',
description='PET is a collection of scripts that gather informatio about your packages',
long_description=long_description,
# The project's main homepage.
url='https://github.com/PET-UnB/pet',
# Author details
author='Tiago Assuncao',
author_email='tiago@sof2u.com',
# Choose your license
license='GPL3',
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
# How mature is this project? Common values are
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
'Development Status :: 5 - Production/Stable',
# Indicate who your project is intended for
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',
'Topic :: Software Development :: Bug Tracking',
'Topic :: Software Development :: Libraries :: Perl Modules',
'Topic :: Software Development :: Version Control',
# Pick your license as you wish (should match "license" above)
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
# Specify the Python versions you support here. In particular, ensure
# that you indicate whether you support Python 2, Python 3 or both.
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
],
# What does your project relate to?
keywords='debian packaging development',
# You can just specify the packages manually here if your project is
# simple. Or you can use find_packages().
packages=find_packages(),
# Alternatively, if you want to distribute just a my_module.py, uncomment
# this:
# py_modules=["my_module"],
# List run-time dependencies here. These will be installed by pip when
# your project is installed. For an analysis of "install_requires" vs pip's
# requirements files see:
# https://packaging.python.org/en/latest/requirements.html
install_requires=[
'pyramid_chameleon',
'SQLAlchemy'
],
# List additional groups of dependencies here (e.g. development
# dependencies). You can install these using the following syntax,
# for example:
# $ pip install -e .[dev,test]
# extras_require={
# 'dev': ['check-manifest'],
# 'test': ['coverage'],
# },
# To provide executable scripts, use entry points in preference to the
# "scripts" keyword. Entry points provide cross-platform support and allow
# pip to create the appropriate form of executable for the target platform.
entry_points={
'console_scripts': [
'pet_serve=pet.serve:pet_serve',
'pet_update=pet.pet_update:pet_update',
],
},
)
Configurando o Manifest.in
editarDentro do empacotamento python, só são transmitidos para a produção os arquivos com extensão .py. Dessa maneira, qualquer aplicação que utilize outros arquivos não será carregado automaticamente. Uma aplicação web, por exemplo, se utiliza de arquivos css, html, etc. A maneira para especificar os arquivos que podem entrar na pasta do empacotamento é utilizando o arquivo manifests.in. Nele pode-se especificar todos os arquivos que devem entrar. No nosso exemplo, tínhamos a necessidade de enviar todos os arquivos com extensão .css, .js e .pt. Então utilizamos a seguinte regra:
# Include the license file
# include README.rst
global-include *.css *.js *.pt
Readme
editarO formato padrão para o readme na pypi é o rst. Você deve converter seu readme para essa extensão, caso não esteja. Ainda sim, pode-se manter os outros formatos.
Makefile
editarPara criar um pacote e fazer upload da sua versão, sempre eram necessários vários comandos repetidos, que serão explicados posteriormente. Para facilitar a tarefa de rodar todos os mesmos comandos todas as vezes em que era necessário fazer uma nova build, um makefile foi gerado, necessitando então, apenas rodar o comando make e o upload é realizado. O makefile utilizado pode ser visto abaixo:
all:
-mv -f dist/* log
python setup.py sdist bdist_wheel
twine upload dist/*
mkdir -p log
mv dist/* log
Registro na Pypi
editarPara fazer o upload, é necessário possuir uma conta na Pypi. O processo é bastante simples.
- Primeiramente, deve-se criar uma conta no site do pyhotn https://pypi.python.org/pypi?%3Aaction=register_form
- Setar seu usuário no seu ambiente de desenvolvimento
Este último passo é realizado com o auxilio de um arquivo de configuração que deve ficar localizado na raiz do usuário do sistema( /home/user ) e deve-se chamar: ~/.pypirc
Um exemplo desse arquivo segue abaixo:
[distutils]
index-servers=pypi
[pypi]
repository = https://upload.pypi.io/legacy/
username = <username>
password = <password>
Caso não queira disponibilizar a senha, pode-se utilizar o upload passando a flag -p PASSWORD.
Processo de geração das builds
editarToda vez que uma nova build é gerada, o setuptools a compila e a transforma em arquivos executáveis, prontos para passarem pelo upload. Para gerar essas builds, o seguinte comando deve ser utilizado:
$ python setup.py sdist bdist_wheel
As builds serão geradas e armazenadas na pasta dist/ Para fazer o upload, deve-se rodar o comando:
$ twine upload dist/*
Assim, já é possível procurar pelo nome do pacote na pypi que ele estará disponível para download. Neste caso, ficou no link: https://pypi.python.org/pypi/pet-debian/