David's Blog

Contribuindo Com Projetos Open Source

Buscando melhorar minhas habilidades como programador ruby, resolvi procurar algum projeto opensource no github, que fosse útil pra mim de alguma forma, e que fosse usado por um bom número de pessoas. Infelizmente, não encontrei nenhum projeto que não fosse tão grande quanto o Rails, ou tão pequeno que ninguém da comunidade ruby realmente usasse, então acabei desistindo da ideia. Um dia, acompanhando o canal de ruby do debian no irc, percebi que alguém havia empacotado o ruby-ghi para a unstable, e por curiosidade fui atrás do projeto usado como upstream para o pacote.

Ghi(https://github.com/stephencelis/ghi) é uma gem ruby, que se comunica com a api do github, e permite gerenciar várias features disponibilizadas pelo github, via terminal. Entre essas features temos:

    - Listagem de issues
    - Listagem de milestones
    - Abrir/Fechar issues
    - Abrir/Fechar milestones
    - Editar issues existentes
    - Assinar issues para alguém, ou para si mesmo

Achei o projeto muito interessante, com um código não tão grande assim, e várias issues relativamente fáceis de serem resolvidas.

A issue que eu escolhi para resolver foi, ao listar as issues de determinado repositório, filtrá-las por milestone:

O maior benefício de contribuir com projetos open source, além de você poder usar essas contribuições no seu currículo, é o ganho que você terá como programador. Uma issue simples como essa que eu peguei para resolver, me fez estudar vários conceitos de ruby que eu não dominava, ou usava sem saber muito o porque(blocks por exemplo). Além de estudar a própria linguagem, projetos open source te mostram outras maneiras de resolver um mesmo problema, ou seja, te trazem visão crítica e te permitem perceber que nem sempre apenas funcionar é o bastante, principalmente quando se trata de projetos com vários contribuidores, que constantemente vão ler o código de outros desenvolvedores. Manutenibilidade deve ser algo primordial em projetos open source.

O pull request que enviei https://github.com/stephencelis/ghi/pull/301

O ghi, apesar de ser um projeto com um tamanho de código fonte médio, não possui testes. Iniciei uma discussão(https://github.com/stephencelis/ghi/issues/302) no repositório sobre essa ausência de testes,e o quanto isso é prejudicial pra evolução do projeto. Espero que em breve possamos adicionar uma boa cobertura de testes para o ghi.

O meu objetivo é encontrar outros projetos opensource para contribuir, e sempre buscar melhorar minhas habilidades como programador.

Configurando Znc Server + Xchat

Por muito tempo eu fiz uso do cliente de irc weechat para conectar em servidores como o freenode, e interagir com as comunidades de SL. Infelizmente a infra da minha faculdade, bloqueia portas altas, inclusive a porta 6667, que é a porta em que o freenode aceita requisições. Uma alternativa que encontrei, foi dentro de uma VM na digital ocean, executar uma seção do tmux, e dentro dessa sessão executar o weechat. Para acessar o irc eu fazia:

    ssh david@<ip_da_minha_vm> -t 'tmux attach; bash -l'

Isso me permitia acessar o freenode, e outros servers(como o oftc), por fora da rede da minha faculdade, além de me manter sempre conectado nos canais do irc, uma vez que a seção do tmux fica sempre aberta, enquanto você não a fecha. Esse workaround me permitiu ficar sempre online no irc, além de conseguir usar o weechat de dentro da infra porca da minha faculdade.

Com o tempo, essa solução se mostrou bem amadora, e por indicação de um amigo, comecei a usar o glorioso znc.

Bouncer é um conceito similar a um proxy. Você acessa ao bouncer com o seu ip, e ele acessa determinado serviço na internet com o ip do servidor aonde ele(o bouncer) está sendo executado. No contexto de servidores irc isso é muito útil, porquê o bouncer sempre ficará online, mesmo que o cliente encerre a requisição. O znc é construido em cima desse conceito, mas te permite fazer diversas configurações a mais, que simplesmente rodar um weechat dentro de uma seção do tmux não permite.

A configuração do znc é muito simples, com um comando você realiza toda a configuração, instala modulos, adiciona canais e servidores, cria usuários no servidor e gerencia suas permissões, entre diversas outras coisas.

    znc --makeconf

Durante essa configuração eu recomendo adicionar o módulo webadmin, que permite gerenciar todas as configurações do znc pelo browser.

Com o znc, o cliente de irc que você tiver usando(no meu caso o xchat), não precisará fazer configuração nenhuma, tudo é feito via znc. A unica coisa que o cliente precisa fazer, é mandar as credênciais de acesso, para poder usar o znc. Em resumo o cliente conecta no znc, e o znc conecta nos servidores irc.

Configurando o cliente

Para acessar n redes irc(freenode e oftc por exemplo) você precisará fazer n requisições a essas determinadas redes. No xchat você pode definir em quais redes o cliente vai se conectar quando a aplicação iniciar. No meu caso eu defini duas redes, o znc-oftc e o znc-freenode. Ambos conectam no mesmo servidor znc, a diferença está no momento de passar as credenciais para o servidor.

O gif abaixo mostra como definir no xchat o endereço e a porta do znc. Essa configuração é a mesma para as duas redes. +

Mas se em ambas as redes, conectamos no mesmo servidor, e na mesma porta, como o znc vai saber que a rede znc-oftc(definida no xchat) tem que ser redirecionada para o servidor irc.oftc.net ? O xchat, dentro das configurações de uma rede, possui o campo password do servidor. É nesse campo que você irá informar o nome do usuário(que foi definida na configuração do znc), a rede que esse usuário quer acessar e a senha desse usuário.

    Ex: davidCarlos/oftc:12345abcd

Isso é expecífico para o xchat, em outros clientes essa configuração pode mudar.

Dessa forma, quando você inicializar o xchat, ele irá conectar no znc, informando o usuário, a sua senha e em para qual rede esse acesso deve ser redirecionado. É no znc que você irá configurar o ip e a porta do servidor oftc, e não no cliente.

WebAdmin

Para configurar o znc via navegador, basta acessar o ip do servidor aonde o znc está rodando:a porta que você definiu no makeconf

Lembre-se que para fazer esse acesso, você precisa habilitar o modulo do webadmin durante a configuração do znc.

Como o znc permite que você adicione vários usuários ao servidor, as possibilidades de uso se estendem para organizações e empresas que querem definir uma configuração padrão de acesso a servidores irc para todos os usuários. O funcionário só precisa conectar no no ip/rede que lhe é de interesse, e todas as configurações(modulos adicionais, scripts, permissões) estarão centralizadas em um único lugar.

OBS: O znc não necessariamente precisa executar no intervalo de portas que é informado no momento do makeconf. No meu caso, o meu znc roda na porta 8081, justamente porque a infra da minha faculdade, bloqueia a saida de pacotes por portas altas.

Preparando Montangem De Pendrive Pelo Arquivo Fstab

Muitas vezes, ao tentarmos montar um pendrive, temos alguns problemas no linux. Um desses problemas é o SO não reconhecer o pendrive no momento em que inserimos o pendrive no pc. Uma forma de listar quais sistemas de arquivo estão montados e em que diretório foram montados é utilizando o comando mount. O problema é que se o linux não reconheceu o pendrive automaticamente, quando executarmos o comando mount, nosso pendrive não será listado. Um forma(não a melhor forma, devo deixar isso bem claro) de contornar esse problema é montar o pendrive manualmente. Para isso iremos utilizar o comando blkid. Esse comando irá nos mostrar os block devices.

Block devices são os dispositivos, no linux, que guardam dados, um pendrive por exemplo. Quando executamos o comando blkid, iremos visualizar o seguinte:

Agora ficou fácil, pois o comando blkid nos mostra o UUID do dispositivo. O UUID é um identificador único para cada sistema de arquivos mantidos pelos block devices.

No arquivo /etc/fstab adicionamos a linha

UUID=D488-3B7E /media/david vfat defaults

O primeiro argumento não precisa ser explicado, o segundo argumento é o diretório em que o block devices será montado, e o terceiro argumento o define o tipo do sistema de arquivos.

Agora para montar o pendrive, basta fazer

 # mount /dev/sdb1

Nesse caso usamos /dev/sdb1 pois foi o que o comando blkid printou na tela, mas poderia ser outro dispositivo.

Devo ressaltar que esse procedimento deve ser feito com cuidado e em ultimo caso, pois ao adicionar um novo ponto de montagem no arquivo /etc/fstab, no momento em que a máquina for iniciada, o kernel irá tentar montar esse device, e caso o pendrive não esteja conectado na máquina, o sistema não irá inicializar corretamente.

Debian: Fazendo Meu Primeiro Pacote - Parte 1

Quando abrimos nosso terminal e digitamos sudo apt-get install mutt, estamos dizendo para o Debian, que queremos instalar um pacote chamado mutt usando o gerenciador de pacotes apt-get e que estamos fazendo isso com permissões de root.

Não irei comentar nesse post como é a política de upload de pacotes no Debian, além do fato de existir muita documentação do Debian relacionado a isso. Basicamente o que irei comentar aqui, são as ferramentas necessárias para criar um pacote para o debian, mais expecificamente um pacote em que o upstream é escrito em python.

Em resumo um pacote Debian é formado por:

 * Diretório debian
 * Código do upstream

Estamos considerando o caso em que não iremos criar um pacote do zero, logo o diretório debian já irá existir. Para baixar a ultima versão do pacote no debian basta fazer:

sudo apt-get source urlscan

Quando baixarmos o source do urlscan três arquivo e um diretório irão aparecer.

  1. urlscan_<version>-<release>.debian.tar.xz: Tarball com o diretório debian
  2. urlscan_<version>.orig.tar.xz: Tarball com o código do upstream inalterado.
  3. urlscan_<version>-<release>.dsc: Arquivo que descreve a versão atual do pacote que acabamos de baixar.
  4. urlscan-<version>: Diretório com o código do upstream + diretório debian

É dentro do diretório debian que iremos definir como o pacote será construido(aonde os arquivos de configuração e os binários gerados serão colocados). Basicamente o diretório debian deve ter no mínimo a os seguintes arquivos:

  1. changelog: Registra tudo que foi feito no pacote e por quem
  2. compat: Define a versão do debhelper a ser usada (atualmente estamos na 9)
  3. control: Define quais as dependências de construção e instalação do pacote, além de informações básicas requeridas pelo Debian, como o nome do pacote, uma breve descrição, e etc.
  4. rules: Define o passo a passo para a construção do pacote. O Debian está ai para te ajudar, então o recomendado é utilizar os helpers do Debian, e deixar que eles façam o trabalho pesado. Pode ocorrer de que o comportamento padrão dos helpers não seja o suficiente, então nesse caso, você pode sobrescrevê-los adicionando o que for necessário.
  5. copyright: Define a licença em que esse pacote será distribuído.
  6. watch: Nesse arquivo você definirá uma regex, que será executada pelo comando uscan, para encontrar novas versões do upstream.

O upstream é a pessoa,comunidade ou organização que desenvolve o código fonte do software que você quer empacotar. Hoje em dia, boa parte dos upstreams estão em plataformas como github, gitlab e sourceforge, então provavelmente seu arquivo watch irá apontar para um desses lugares.

O upstream que iremos empacotar será o urlscan(https://packages.qa.debian.org/u/urlscan.html). Esse programa faz o parser de arquivos html e extrai e apresenta urls de uma maneira amigável. Esse pacote deve ser usado com um cliente de email que rode no terminal, como é o caso do mutt.

O primeiro passo a se fazer é tentar construir o pacote dentro do seu ambiente de empacotamento(no meu caso eu uso o vagrant com o debian sid). Vale lembrar que sempre que formos empacotar algo para o debian, obrigatoriamente temos que estar em um ambiente debian unstable.

Abra o arquivo control dentro do diretório debian, e veja quais os pacotes foram colocados como dependência(Build-Depends-Indep). Iremos precisar instalá-los para que o pacote possa ser construído.

Com todas as dependências instaladas, e estando na raiz do diretório urlscan-<version> execute o comando debuild. Se tudo der certo teremos, um diretório acima do diretório raiz do source, um pacote .deb do urlscan.

Continuamos no proximo post =) .

Vim: Salvando Arquivos Como Sudo

Esse é o primeiro post deste blog pessoal, e obvimente eu não poderia falar de outra coisa, se não a ferramenta que eu mais uso durante o tempo em que estou no pc, o vim. Será um post curto, então vamos ao que interessa.

Quando abrimos aquele arquivo que precisa de permissão de root para ser editado, é muito chato ter que sair do vim e abrir o arquivo com sudo.

Edite seu arquivo normalmente, e no momento de salvá-lo, ao invés de sair do vim e entrar como sudo (você pode executar o seu ultimo comando como sudo apenas fazendo sudo !!), basta fazer:

   :w !sudo tee %

O vim pode pedir sua senha de sudo ou salvar automaticamente caso você já tenha usado alguma comando com sudo antes. Você pode mapear esse comando no seu vimrc para facilitar na hora de salvar o arquivo. No meu vimrc eu fiz o seguinte mapeamento:

    nmap <LEADER>R :w !sudo tee %<CR>

Aonde <LEADER> equivale a virgula, nas minhas configurações. Lembrando que para sair do arquivo você irá precisar forçar com :q!