Criando Aplicações Integradas de Alta Qualidade para Linux

2.1 :: 2002-08-24

Avi Alkalay

Senior IT and Software Architect :: Linux Market Developer
IBM Linux Impact Team :: ibm.com/linux

1. Introdução
2. Amigável ao Usuário: Garantia de Sucesso
2.1. Adote o paradigma Instalar-e-Usar
3. As Quatro Partes Universais de Qualquer Software
3.1. Exemplos Práticos
3.2. Importância da Clara Separação Entre as Quatro Partes
3.3. Um Corpo, Muitas Almas
4. Hierarquia de Diretórios do Linux: Orientada às Partes do Software
4.1. Resumo do FHS
4.2. Exemplo Usando o FHS
4.3. Desenvolvedor, Não Instale em /opt ou /usr/local !
5. Forneça Arquitetura Para Extensões e Plugins
5.1. Abstraindo sobre Plugins
6. Sempre Forneça Pacotes RPM de Seus Softwares
6.1. Modularizando seu Software
7. Segurança: O Conceito Onipresente
8. Interfaces Gráficas
8.1. KDE, GNOME, Java ou Motif?
8.2. Interface Web: Acessível de Qualquer Lugar
8.3. Wizards e Instaladores Gráficos
9. Iniciando Seu Sistema Automaticamente no Boot
9.1. Da BIOS aos Subsistemas
9.2. Runlevels
9.3. Os Subsistemas
9.4. Fazendo seu Software Ser um Subsistema
9.5. Empacotando seu Script
A. Red Hat, Sobre a Estrutura do Filesystem
B. Sobre este Documento

1. Introdução

O Linux está cada vez mais popular, e muitos fabricantes de Software estão portando seus produtos de outras plataformas. Este documento (artigo) tenta esclarecer algumas dúvidas e dar dicas de como criar aplicações para Linux, visando uma ótima integração com o Sistema Operacional, facilidade ao usuário e segurança.

Os exemplos foram testados em Red Hat Linux, e devem ser compatíveis com outras distribuições baseadas em Red Hat (Conectiva, Turbolinux, Caldera, PLD, Mandrake, etc).

2. Amigável ao Usuário: Garantia de Sucesso

O conceito de user-friendly é erradamente associado a uma boa interface gráfica com o usuário. Na verdade vai muito além disso. Em sistemas como o Linux (que tem características mais fortes de servidor), o usuário mede a facilidade principalmente na instalação e configração inicial de um software. Ele pode até esquecer como foi fácil instalar e usar um certo produto, mas nunca vai esquecer que um software tem um processo de instalação complexo e demorado. Uma migração ou nova instalação será sempre um pesadelo, fazendo o usuário evita-la. Para piorar, uma má experiência de usuário com seu produto poderá queimar o filme de sua empresa.

2.1. Adote o paradigma Instalar-e-Usar

Imagine que você vai instalar aquele produto caríssimo que sua empresa comprou da ACME, e descobre que terá de fazer o seguinte:

  1. Ter um manual que mostra passo a passo o processo de instalação. Na prática sabemos que manual é a última coisa que o usuário lê

  2. Ler arquivos README

  3. Descompactar no disco enormes arquivos (depois de baixa-los da rede ou do CD), para criar o ambiente de instalação

  4. Ler mais arquivos README que surgiram na descompactação

  5. Entender que para instalar terá que executar de uma forma especial algum script fornecido (o inconveniente ./install.sh)

  6. Desconfortavelmente responder a perguntas que o tal script faz, tais como diretório de instalação, usuário de instalação, etc. Para piorar, frequentemente isto ocorre num terminal com o backspace mal configurado

  7. Configurar variáveis de ambiente em sua profile, tais como $PATH, $LIBPATH, $ACMEPROGRAM_DATA_DIR, $ACMEPROGRAM_BIN_DIR, etc

  8. Editar arquivos do sistema para incluir a presença do novo produto (ex: /etc/inetd.conf, /etc/inittab)

  9. E o pior: Alterar permissões de segurança de diretórios e arquivos do SO, para que o produto funcione bem

Soa familiar? Quem nunca passou por essa triste situação, que induz o usuário a cometer erros? Se o processo de instalação de seu produto é Descompactar-Copiar-Configurar-ConfigurarMais-Usar, como o acima, você tem um problema, e o usuário não vai gostar.

Usuários gostam de sentir que seu Produto se integra bem ao SO. Não deve exigir que o SO se adapte ao seu Produto (alterando variáveis de ambiente, etc). Deve permitir o usuário Instalar-e-Usar.

A gloria do Instalar-e-Usar é facilmente atingida usando uma receita de 3 ingredientes:

  1. Compreendendo as Quatro Partes Universais de Qualquer Software

  2. Entendendo como eles se relacionam com a hierarquia de diretórios do Linux

  3. Usar agressivamente um sistema de pacotes para operacionalizar isso, e automatizar processos. No nosso caso é o RPM.

Vamos discutir aqui o que são estes ingredientes, e como implementa-los

3. As Quatro Partes Universais de Qualquer Software

O conjunto de arquivos de qualquer Software, seja ele gráfico, de servidor, comercial, aberto/livre, monolítico etc, tem sempre 4 partes universais:

1a :: O Software em Sí: o corpo

São os executáveis, bibliotecas, arquivos de dados estáticos, manuais e documentação, exemplos etc. O usuário comum poder ter somente acesso de leitura a estes arquivos. Eles são alterados somente quando administrador do sistema faz um upgrade neste Software.

2a :: Arquivos de Configuração: a alma

São arquivos que definem como o Software vai rodar, como usar o Conteúdo, parametrizam a segurança, performance etc. Sem eles, o Software em Sí geralmente não é usável.

Dependendo do seu Software, usuários com permissões específicas devem poder alterar estes arquivos, para faze-lo funcionar da forma que lhes convier.

é importante fornecer manuais sobre as possíveis configurações.

3a :: Conteúdo

é o que recebe toda atenção de seu usuário. é o que o usuário confiou ao seu Produto gerenciar. é o que fará, se for danificado, o usuário se livrar de seu produto, e procurar um concorrente seu.

São as tabelas para um banco de dados, os documentos de um editor de textos, as páginas HTML e imagens de um web-server, os servlets e EJBs de um Application Server etc.

4a :: Logs, Dumps etc

Geralmente os Softwares de servidor geram logs de acesso, arquivos de trace para identificar problemas, arquivos temporários, etc. Outros Softwares também lançam mão destes tipos de arquivos, talvez com menos freqüencia.

é a última das classes de arquivos, mas muitas vezes é a que mais causa problemas para um administrador de sistemas, pois seu volume pode ultrapassar o do próprio conteúdo. Por isso é importante pensar em alguma metodologia ou facilidade neste ponto enquanto você ainda está criando seu produto.

3.1. Exemplos Práticos

Vamos ver a universalidade do conceito acima analizando alguns tipos aleatórios de softwares:

Tabela 1. Universalidade das 4 Partes

 Software em SíConfiguraçõesConteúdoLogs, Dumps etc
Servidor de Banco de DadosBinários, bibliotecas, documentação.Arquivos que definem o diretório dos arquivos das bases de dados. Para esta classe de Software, o restante das configurações geralmente estão em tabelas especiais dentro da base de dados.Arquivos de tabelas, indices, etc. Geralmente estes softwares trabalham com árvores inteiras sob um mesmo diretório. E muitas vezes precisam de vários filesystems diferentes para garantirem performance. Sua localização no sistema é definida pelas Configurações.Para DBs há também o backup, gerado diariamente. E os logs são usados pelo DBA para definir estratégia de indexação das tabelas. Sua localização etc são também definidas pelas Configurações.
Editor de TextosIdem, templates, filtros modulares de formatos, etcSendo um programa orientado ao usuário, suas configurações devem ficar no $HOME de cada um, e são os arquivos que definem fonte padrão, tabulação padrão, etcOs documentos gerados pelo usuário, geralmente em algum lugar de seu $HOMEAparecem como arquivos temporários que podem ser enormes. O usuário pode definir sua posição através de algum diálogo amigável (que grava em algum arquivo de Configuração)
Gerador de MP3Idem, filtros modulares de audioCada usuário tem o seu no $HOME, e contém preferências de bitrate etcSemelhante ao do Editor de TextosSemelhante ao do Editor de Textos
Web ServerIdemArquivos que definem os diretórios do Conteúdo, parâmetros de rede e performance, segurança, etcDiretórios em que o webmaster deposita sua criatividade. Localização novamente definida pelas ConfiguraçõesPreciosos logs de acesso, vitais para a Inteligência de Marketing, que são gerados num formato e diretório definidos pelas Configurações
Servidor de e-mailIdemArquivos que definem como acessar base de dados de usuários, regras de roteamento de mensagens, etcAs preciosas caixas postais dos usuários. Localização definida pelas ConfiguraçõesLog de tráfego, log de detecção de virus, arquivos de mensagens temporárias, etc. novamente definido pelas Configurações.

Percebam como o Software em Sí contém toda a lógica de negócio de seu produto, que seria inútil se não houvesse uma Configuração para definir como trabalhar com uma massa de dados, provida pelo usuário. Ou seja, as Configurações são o que ligam seu produto ao usuário.

Podemos pensar numa metáfora sobre um Escultor (software em sí), que precisa receber Bronze (conteúdo) e um Tema ou Inpiração (configuração) de um Mecenas (usuário), para produzir uma bela Obra (conteúdo). Ele anota em seu Diário (logs) as atividades de cada dia para relatar ao seu Mecenas (usuário) que está produzindo.

3.2. Importância da Clara Separação Entre as Quatro Partes

OK, então vamos ser mais práticos. O fato é que se aplicarmos corretamente o conceito das partes universais, aumentamos enormemente a qualidade de nosso produto. Faremos isso simplesmente separando, encapsulando, cada uma dessas partes em diretórios diferentes (separar em arquivos não é suficiente). Existe um padrão chamado Filesystem Hierarchy Standard que define os diretórios do Linux para cada parte, e vamos discutir isso mais tarde na Secção 4, “Hierarquia de Diretórios do Linux: Orientada às Partes do Software”.

Por enquanto vamos ver o valor disso para o usuário:

  1. Ele passa a ter muito mais clareza de onde está cada coisa, pricipalmente suas Configurações e Dados, e passa a enchergar o seu produto como algo completamente controlado. A clareza traz facilidade, segurança e sobretudo confiança em seu protudo. E na prática isso permite-o manipular cada uma das partes independentemente

  2. Fica claro que para um backup, por exemplo, o usuário deve agir somente sobre Configurações e Conteúdo (para os puritanos, os logs também interessam). Não é obrigatório se preocupar com o Software em Sí, pois está são e salvo, idêntico, no CD do produto, no armário do usuário

  3. Para upgrades, o pacote novo sobrescreve somente a lógica de negócio, deixando intactos os valiosos Conteúdo e Configurações do usuário. é muito importante aqui seu Software manter compatibilidade com versões antigas, ou prover alguma facilidade para migrações

  4. Estando os logs em filesystem separado (obviamente sugerido no manual de seu produto), evitam que seu crecimento exagerado interfira no conteúdo, ou no bom funcionamento do resto do sistema

  5. Com seu Software seguindo alguns padrões de diretórios, o usuário não terá que reconfigurar o sistema ou ambiente para usar seu produto. Irá simplesmente Instalar-e-Usar.

Vamos exercitar a separação com um exemplo de um sistema chamado MySoftware, em que a lógica de negócio está puramente no Exemplo 1, “Programa em Shell fazendo referência a configurações externas” e a configuração está em Exemplo 2, “Arquivo contendo somente as configurações para MySoftware”.

Exemplo 1. Programa em Shell fazendo referência a configurações externas

#!/bin/sh

#############################################################################
##
## /usr/bin/MySoftware
##
## Business logic of MyProgram system.
## Do not change nothing in this file. All configuration can be
## made on /etc/MySoftware.conf
##
## We'll not support any modifications made here.
##

# Default configuration file
CONF=/etc/MySoftware.conf	1

# Minimal content directories
MIN_CONTENT_PATH=/var/www:/var/MySoftware/www	2

if [ -r "$CONF"]; then
        . "$CONF"	3
fi

# All the content I'll serve are the "minimal" plus the ones provided
# by the user in the configuration file $CONF
CONTENT_PATH=$MIN_CONTENT_PATH:$CONF_CONTENT_PATH	4

.
.
.
1

Definição do nome do arquivo de configuração.

2

Definição de alguns parâmetros estáticos ao produto.

3

A configuração é lida de um arquivo externo, se existir.

4

Após a leitura da configuração, todos os diretórios de conteúdo -- do usuário + do produto -- são colocados na $CONTENT_PATH, que será usada daqui para frente.

Exemplo 2. Arquivo contendo somente as configurações para MySoftware

#############################################################################
##
## /etc/MySoftware.conf
##
## Configuration parameters for MySoftware.
## Change as much as you want.
##

# Content directory.
# A ':' separated list of directories for your content.
# The directories /var/www and /var/MySofware are already there, so
# include here your special directories, if any.
CONF_CONTENT_PATH=/var/NewInstance:/var/NewInstance2	1

# Your e-mail address, for notifications.
EMAIL=john@mycompany.com	2

# Logs directory
LOG_DIR=/var/log/myInstance	3
1 2 3

O usuário define estes parâmetros.

3.3. Um Corpo, Muitas Almas

Quando eu era o administrador de sistemas para IBM e-business Hosting Services, eu era fascinado pela flexibilidade do Apache permitindo fazer coisas deste tipo:

bash# /usr/sbin/httpd &
bash# /usr/sbin/httpd -f /etc/httpd/dom1.com.br.conf &
bash# /usr/sbin/httpd -f /etc/httpd/dom2.com.br.conf &
bash# /usr/sbin/httpd -f /etc/httpd/dom3.com.br.conf &

Se não passassemos nenhum parâmetro (como no primeiro exemplo), o Apache carregava seu arquivo de configuração default, hardcoded, de /etc/httpd/conf/httpd.conf. Nós criamos outras configurações, uma para cada cliente, com uma estrutura completamente differente, endereço IP, módulos carregados, diretório de conteúdo, senhas, domínios, estratégia de log etc.

Este mesmo conceito é usado por um editor de texto de um desktop multiusuário (como o Linux). Quando o código é carregado, ele procura por um arquivo de configuração no $HOME do usuário, e dependendo quem o invocou (usuário A ou B), aparecerá diferente porque cada um tem sua própria configuração pessoal.

A conclusão óbvia é que o corpo (lógica de negócio) do Software é puro e completamente orientado pela alma (configuração) de quem o manipula. Mas a vantagem competitiva está na facilidade de como trocamos uma alma pela outra, como no caso do Apache. é muito saudável você promover isto ao seu usuário, pois lhe permite criar intimidade, conforto, segurança com seu Produto.

Usamos essa abordagem com muito diferentes Software naqueles tempos de e-business Hosting, e era extremamente prático para manutenções etc. Numa migração de versão, tinhamos controle total de onde estava cada uma de suas partes, e faziamos upgrades e downgrades sem perder tempo, com sucesso óbvio.

Mas haviam uns Softwares que se recusavam a trabalhar desta forma. Tinham tantos parâmetros hardcoded, que não conseguiamos enchergar com clareza o que separava o corpo de sua alma (ou outras partes). Marcavamos estes Produtos como os de sangue ruim, e os descartávamos/trocávamos assim que possível.

Concluimos que os Softwares de sangue bom foram intuitivamente abençoados pela visão das quatro partes de seus desenvolvedores. E eles fizeram nossa vida mais fácil. De fato, foi nessa época que formulamos essa teoria, e ela continua se comprovando.

Você quer criar Software sangue ruim ou sangue bom?

4. Hierarquia de Diretórios do Linux: Orientada às Partes do Software

Toda a discussão até aqui era independente de sistema operacional. No Linux, a lei das Quatro Partes do Software se expressa em sua hierarquia de diretórios, que é classificada e documentada no Filesystem Hierarchy Standard. O FHS faz parte do LSB (Linux Standard Base), o que faz dele uma coisa boa pois toda a indústria está se movendo em sua direção, e é uma preocupação constante de todas as distribuições. é o FHS que define em que diretórios cada pedaço do Apache, do Samba, Mozilla, KDE e de seu Software será colocado, e você não tem mais nenhum motivo para não usa-lo quando pensar em desenvolver seu software, mas vou dar mais alguns:

  1. O FHS é um padrão, e padrões são vitais

  2. Esta é a organização mais básica do Sistema Operacional, que se relaciona com níveis de acesso e segurança, onde usuários intuitivamente encontram cada tipo de arquivo, etc

  3. Facilita a vida do usuário final

Só este último já justifica sua adoção, então use sempre o FHS !!!

Mais sobre a importância do FHS e sobre compartilhar a mesma estrutura de diretórios pode ser encontrado no site da Red Hat

4.1. Resumo do FHS

Então vamos resumir o que o FHS diz sobre as pastas (diretórios) do Linux:

As Pastas do Linux

/usr/bin

Pasta para executáveis que são acessados por todos os usuários (todos tem este diretório em seu $PATH). Os principais arquivos de seu Software provavelmente estarão aqui. Nunca crie nenhuma sub-pasta dentro dela.

/bin

Como o /usr/bin, mas aqui só estão os executáveis vitais para o processo de boot que são simples e pequenos. Seu Software (por ser de alto nível) provavelmente não tem nada o que instalar aqui.

/usr/sbin

Como o /usr/bin, mas contém somente executáveis que são acessados pelo administrador (usuário root). Usuários normais nunca devem ter este diretório em seu $PATH. Se seu Software é um daemon, este é o lugar para alguns de seus executáveis.

/sbin

Como o /usr/sbin, mas somente para os executáveis vitais para o processo de boot, e que devem ser usados pelo administrador para alguma manutenção. Comandos como fsck (manutenção do disco), init (o pai de todos os processos), ifconfig (configuração de rede), mount, etc residem aqui. é a pasta mais vital do sistema.

/usr/lib

Contém bibliotecas dinâmicas e arquivos estáticos de suporte para os executáveis em /usr/bin e /usr/sbin. Você pode criar uma subpasta do tipo /usr/lib/meuproduto para depositar seus arquivos de suporte, ou bibliotecas dinâmicas que serão acessadas somente pelo seu produto, sem intervenção do usuário. Um subdiretório aqui pode ser usado como container para plugins e extensões.

/lib

Como /usr/lib mas contém bibliotecas dinâmicas e arquivos de suporte necessários para o processo de boot. Você nunca vai encontrar um executável em /bin ou /sbin que precisem de bibliotecas que estão fora deste diretório. Os módulos do Kernel (drivers de dispositivo) estão sob /lib.

/etc

Contém os arquivos de configuração. Se seu Software tem vários, coloque-os numa subpasta chamada /etc/meuproduto/

/var

O nome vem de "variável", porque tudo que está sob esta pasta muda muito, e o sistema de pacotes (RPM) não controla. Geralmente é montado noutra partição, para ganharmos performance. Em /var/log crescem os logs. Para conteúdo web existe o /var/www. E assim por diante. Resumindo, tudo que não é controlado pelo RPM fica sob o /var.

/home

Contém as pastas "lar" the cada usuário (seres humanos reais). Seu Software não deve nunca instalar arquivos aqui (em tempo de instalação). Se sua lógica de negócio necessita um usuário (não um ser humano) UNIX especial a ser criado, você deve lhe associar um diretório sob /var ou outro lugar fora do /home. Por favor nunca esqueça disso.

/usr/share/doc, /usr/share/man,

Usa-se a palavra "share" porque o que está sob /usr/share é independente de plataforma, e pode ser compartilhado entre várias máquinas através de um sistema de arquivos em rede. Portanto aqui é o lugar dos manuais, documentação, exemplos etc.

/usr/local, /opt,

Estas pastas são obsoletas. Quando o UNIX não tinha um sistema de pacotes (como RPM), os administradores precisavam separar um software opcional (ou local) do resto do SO. Estas eram as pastas usadas para isso.

Pode parecer uma má idéia quebrar seu Software (como um todo) em vários pedaços, ao invés de mante-lo todo em uma pasta self-contained. Mas um sistema de pacotes (RPM) tem uma base de dados que faz tudo isso para você de uma forma muito profissional, mantendo controle de arquivos de configuração, diretórios etc. E se você espalhar seu Software usando o FHS, além da facilidade ao usuários, você propiciará uma forma intuitiva ao administrador configura-lo, e trabalhar melhor com performance e segurança.

4.2. Exemplo Usando o FHS

Agora que sabemos onde cada parte de nosso Software deve ser instalada, vamos rever a Tabela das Partes Universais cruzada com o FHS.

Tabela 2. Mesmos Softwares, aplicando o FHS

 Software em SíConfiguraçõesConteúdoLogs, Dumps etc
Servidor de Banco de Dados/usr/bin/, /usr/lib/, /usr/share/doc/mydb/, /usr/share/doc/mydb/examples//etc/mydb//var/db/instance1/, /var/db/instance2/, etc/var/db/instance1/transactions/, /var/log/db/access-instance1.log, /var/log/db/access-instance2.log
Editor de Textos/usr/bin/, /usr/lib/, /usr/lib/myeditor/plugins/, /usr/share/myeditor/templates/, /usr/share/doc/myeditor/$HOME/.myeditor.conf$HOME/Docs/$HOME/.myeditor-tmp/
Gerador de MP3/usr/bin/, /usr/lib/, /usr/lib/mymp3/plugins/, /usr/share/doc/mymp3/$HOME/.mymp3.conf$HOME/Music/$HOME/.mymp3-tmp/
Web Server/usr/sbin/, /usr/bin/, /usr/lib/httpd-modules/, /usr/share/doc/httpd/, /usr/share/doc/httpd/examples//etc/httpd/, /etc/httpd/instance1/, /etc/httpd/instance2//var/www/, /var/www/instance1/, /var/www/instance2//var/logs/httpd/, /var/logs/httpd/instance1/, /var/logs/httpd/instance2/
Servidor de e-mail/usr/sbin/, /usr/bin/, /usr/lib/, /usr/share/doc/mymail//etc/mail/, /etc/mailserver.cf/var/mail//var/spool/mailqueue/, /var/logs/mail.log

4.3. Desenvolvedor, Não Instale em /opt ou /usr/local !

Se você é um administrador de sistemas, saiba que esta seção não é para você. Esse é um assunto para desenvolvedores e empacotadores, para facilitar a vida do administrador de sistemas.

Os diretórios /opt e /usr/local são usados pelos administradores para instalar manualmente softwares com arquivos soltos (sem RPM), justamente para ele não perder o controle sobre eles. Repare como esses diretórios ficam separados do resto do sistema.

Um processo de instalação manual (sem RPM, ou baseado em simples cópia de arquivos) fica num documento esquecido dentro do armário (se foi documentado), e na cabeça de quem instalou. Se ele mudar de emprego, aquela instalação fica obscura para o resto da equipe, e é uma bomba relógio.

Com RPM é diferente. RPM (ou qualquer outro sistema de pacotes) é um "processo" de instalação em sí. Está auto documentado na forma de sua base de dados e ações de pré e pós-instalação, o que permite controle total. Torna as instalações independentes de quem instalou, e por isso é processo de negócio.

Instalações baseadas em copia de arquivos para /opt ou /usr/local nem de longe provê a organização, visibilidade de sistema e controle do RPM. Diria até que /opt e /usr/local seriam obsoletos se todos os softwares fossem distribuidos como pacotes RPM.

É muito importante para a evolução e popularização do Linux (sobretudo no campo de batalha do desktop) que desenvolvedores parem de usar /opt e /usr/local, e comecem a integrar a instalação de seus produtos à árvore principal do sistema. Se depois de ler esta seção você (como desenvolvedor de software) ainda acreditar que estes diretórios são um bom negócio, por favor mande-me um e-mail.

Produtos que são inteiramente instalados sob um diretório (a rasão da existêcia de /opt e /usr/local), usam a abordagem self-contained, que tem os seguintes problemas:

  1. Força o usuário a alterar variáveis de ambiente como $PATH e $LD_LIBRARY_PATH para usar seu produto.

  2. Coloca os arquivos em locais não-padrão, dificultando a integração com o sistema, e a futura instalação de extensões ao seu produto.

  3. O administrador do sistema provavelmente não alocou espaço em disco para estas partições, causando transtornos no tempo de instalação.

  4. É uma abordagem aceitável somente para aplicações puramente gráficas, sem o conceito de linha de comando. Por isso ele foi bem aceito no Windows. Mas...

  5. ...mesmo usando esta abordagem, não se consegue escapar da necessidade de fazer alterações em arquivos ou diretórios padrão para, por exemplo, fazer seus ícones aparecerem automaticamente no desktop do usuário.

Muitos desenvolvedores acreditam que a abordagem "self-contained" lhes permite trabalhar com várias versões de um mesmo produto simultaneamente, parar testes, ou o que seja. Sim, concordo, com este ou qualquer outro bom motivo do planeta. Mas lembre que um Software de Alta Qualidade (ou Comercial) tem como objetivo a praticidade ao usuário final, e não a facilidade para quem o desenvolve ou testa. Visite um usuário inexperiente (mas potencial cliente) e veja-o instalando seu produto.

Desenvolvedor, não tenha medo de espalhar seus arquivos de acordo com o FHS (livrando-se de /opt e /usr/local), porque o RPM estará de olho neles.

Se você tem uma necessidade de negócio de permitir o usuário trabalhar com várias versões de seu Produto simultaneamente (ou qualuqer outro motivo), faça um pacote relocalizável (relocatable package), cuja descrição está no livro Maximum RPM. Esteja a par também das implicações de usar este recurso, descritos no mesmo livro.

Não é a toa que distribuições como Red Hat e seus derivados usam sempre o padrão de diretórios, ao invés de /opt ou /usr/local. Veja o que a Red Hat fala sobre este assunto, e pense nisso.

[Note]Nota

Os Makefiles de um Software OpenSource, portável a outros UNICES devem ter como padrão a instalação em /usr/local por questões de compatibilidade. Mas devem dar a opção, e induzir o empacotador, a criar o pacote usando especificações do FHS.

5. Forneça Arquitetura Para Extensões e Plugins

Você provavelmente vai querer permitir que outros fabricantes possam plugar extensões ao seu produto. Como você é o autor do Software inicial, cabe-lhe organiza-lo de tal forma que o usuário possa instalar o RPM da extensão e sair usando, sem força-lo a mexer em nenhum arquivo de configuração. é novamente o famoso Instalar-e-Usar que garante facilidade ao usuário.

Ora, uma extensão nada mais é do que alguns arquivos em um formato correto (DLLs que implementam a API que seu Software definiu), colocados em diretórios corretos (pastas em que seu Software procura por extensões). Tem-se visto muitas aplicações em que além da instalação dos arquivos é necessário alterar arquivos de configuração para "declarar" a presença do novo plugin. Isto deve ser evitado por dificultar a vida do usuário ou do fornecedor da extensão, além de ser desnecessário.

Uma boa arquitetura para extensões tem a ver com documentar um diretório qualquer e tudo que se colocar alí será tratado como um plug-in. Um bom candidato para isso é /usr/lib/meuproduto/plugins ou /usr/share/meuproduto/plugins (se as extensões forem independentes de plataforma). Se algum RPM instalar algo que não atenda sua definição de plug-in, cabe a robustez de seu Software detectar e ignora-lo.

5.1. Abstraindo sobre Plugins

Gostaria de fechar este assunto convidando o leitor a se abstrair e pensar em que qualquer Software pode ser tratado como uma extensão ao Software de nível superior. Então da mesma forma que um plugin de terceiros é uma extensão ao seu Software, seu Software acaba sendo uma extensão ao SO (nível superior). Podemos então aplicar todos os conceitos de facilidade ao usuário etc que discutimos anteriormente, para o desenho da arquitetura de plugins de seu Software.

6. Sempre Forneça Pacotes RPM de Seus Softwares

Isso é extremamente importante por vários motivos:

  1. Facilidade ao usuário. Este é sempre o motivo primordial.

  2. Automatiza algumas tarefas que devem ser feitas antes e depois de instalar seu Software. Novamente trazendo facilidade.

  3. Gerencia inteligentemente arquivos de configuração, documentação etc, dando mais controle num upgrade.

  4. Gerencia interdependências com outros pacotes e versões, garantindo bom funcionamento.

  5. Permite distribuir Software com a assinatura digital da sua empresa, e faz verificação de integridade (MD5) em cada arquivo, garantindo procedência, e relatando alterações indevidas.

  6. Traz ferramentas que auxiliam a interação com seu instalador gráfico.

Mas um bom pacote não é simplesmente empacotar todos seus arquivos num RPM. O FHS deve ser respeitado, arquivos de configuração e documentação devem estar marcados como tal, e scripts de pré- e pós-instalação devem ter qualidade, para não danificar o sistema.

Conheça bem o RPM pois ele pode trazer muito poder e facilidade para você a ao usuário. Há muita documentação sobre ele na Internet e em livros. Eis algumas referências:

6.1. Modularizando seu Software

De ao usuário a opção de instalar somente a parte de seu Software que ele precisa. Imagine que seu Software tenha a parte cliente e servidor, e ambos usam alguns arquivos ou bibliotecas em comum. Quebre então em 3 RPMs. Como exemplo, imagine que o nome de seu produto é MyDB, então você fornecerá os pacotes:

  1. MyDB-common-1.0-3.i386.rpm

  2. MyDB-server-1.0-3.i386.rpm

  3. MyDB-client-1.0-3.i386.rpm

sendo que os dois últimos dependem do primeiro. Se o usuário está instalando o sistema com perfil de cliente, usará:

  1. MyDB-common-1.0-3.i386.rpm

  2. MyDB-client-1.0-3.i386.rpm

E se o perfil for de servidor:

  1. MyDB-common-1.0-3.i386.rpm

  2. MyDB-server-1.0-3.i386.rpm

Esta abordagem ajuda o usuário a economizar espaço em disco, e ficar ciente de como seu Software está organizado.

7. Segurança: O Conceito Onipresente

Em linhas muito gerais, segurança é sinônimo de ordem, de consciência. E inseguro é tudo aquilo que faz um sistema parar sem o desejo do usuário. Então além de portas de rede abertas, ou criptografia fraca (que estão fora do escopo deste documento), uma aplicação que induz o usuário a usa-la somente como root, ou faze-lo alterar arquivos em lugares indevidos, é considerada insegura. O mesmo se diz para outra que lota uma partição de disco que é vital ao sistema.

Muitos padrões nasceram de boas práticas discutidas e desenvolvidas em conjunto por muito tempo. Portanto conheça e use-os quando for empacotar seu Software, porque eles são uma peça chave para que você atinja um bom nível de organização (segurança).

8. Interfaces Gráficas

Todos nós gostamos de interfaces gráficas. Muitas vezes facilitam nossa vida e por isso ajudam a popularizar um software, pois diminuem a curva de aprendizado. Mas para o dia-a-dia, um comando com muitas opções e um bom manual acaba sendo muito mais prático, facilitando automações, acesso remoto etc. Então a sugestão é que sempre que for possível, forneça ambas as interfaces: a gráfica para o principiante, e a linha de comando para o experiente.

8.1. KDE, GNOME, Java ou Motif?

Melhor do que uma simples interface gráfica, é um desktop integrado consistente. Portanto desenvolvedor, não reinvente a roda. O que já existe de desktop no Linux é completo, com APIs que facilitam muito sua vida.

Os desktops que hoje reinam na Linuxlândia são o KDE e o GNOME. Tente sempre usar um dos dois, ou ambos.

O KDE é o que mais tem se destacado, oferecendo um verdadeiro desktop consistênte, flexível, e de arquitetura extremamente elegante, incorporando componentes (como COM e COM+ da Microsoft), intercomunicação, performance etc. Está constantemente se aprimorando, e é desenvolvido em C++. Suas aplicações tem um "look-and-feel" integrado e familiar, é leve e maduro. Dizem que o KDE 3 é um diamante lapidado pronto para ser usado, e é a minha principal sugestão para você.

O GNOME também traz a proposta de desktop integrado, mas está longe da maturidade e facilidade do KDE. Por outro lado, é muito bem suportado pela comunidade, e ótimas melhorias vem surgindo.

O Motif não é um desktop integrado. É uma bilioteca de widgets (botão, scrollbar etc), mais um gerenciador de janelas. Ele nasceu comercial, é maduro e bastante usado em aplicações legado. Mas é considerado obsoleto perante o KDE e GNOME, que integram o desktop. O código fonte do Motif foi aberto pelo OpenGroup e por isso também renomeado para OpenMotif.

Java tem sido muito usado para interfaces gráficas, principalmente em Softwares de servidor, onde a interação gráfica é somente um auxílio para a configuração e administração. A Abstract Windowing Toolkit (AWT) do Java, como o próprio nome diz, é independente de desktop. Use interfaces Java para aplicações de usuários específicos, que não necessitem integração com o desktop, ou que não as usarão todos os dias.

8.2. Interface Web: Acessível de Qualquer Lugar

Hoje todo desktop tem um browser, e se seu Software for uma aplicação de servidor, a Interface Web é a escolha certa, por permitir que seja administrado de qualquer lugar. Mas tenha sempre em mente a segurança e organização de seus CGIs, pois eles costumam ser a porta de entrada para crackers. Interface web (CGI) é um paradigma completamente diferente de programação. Tente entende-lo conceitualmente primeiro, passando por como um web-server funciona, o que é uma URL, etc, para se aventurar nisso sem comprometer a segurança de seu produto.

8.3. Wizards e Instaladores Gráficos

Principalmente se for um produto comercial, seu Software deve fornecer um instalador gráfico. Acredite, eles impressionam numa demonstração, e CIOs gostam deles.

Mais que instalação, um wizard auxilia na configuração inicial de um produto, além de coletar dados como chave de ativação etc, e também mostrar a licensa do fabricante.

Um wizard não deve fazer mais do que isso:

  1. Coletar dados de quais módulos instalar, percebidos pelo usuário como checkboxes.

  2. Coletar dados necessários para criar uma configuração (a alma) inicial para seu Software.

  3. Instalar os módulos, que na realidade são arquivos RPM. Cada checkbox deve representar um ou mais RPMs, porque cada RPM é uma porção indivisível (atômica) de um Software.

  4. Após a instalação dos RPMs, alterar os arquivos de configuração (alma) (marcados desta forma nos RPMs), ou criar algum conteúdo, baseado nos dados que o usuário forneceu.

Ou seja, o wizard facilita a instalação de RPMs e cria alguma personalização. A responsabilidade de colocar todos os arquivos de seu Software nos lugares corretos é ainda do RPM. Seu instalador nunca deve tomar esta responsabilidade para sí. Pense que um administrador de sistemas experiente (há muitos deles no mundo Linux) deve poder reproduzir a instalação de seu Software sem seu instalador gráfico, usando somente comandos do RPM. De fato, em grandes CPDs, onde se instala software em massa, um instalador gráfico só atrapalha.

O RPM traz ferramentas que auxiliam seu instalador gráfico interagir com ele, tais como um medidor de porcentagem de instalação. Documentação para seu uso estão no manual (man rpm) e no livro Maximum RPM.

9. Iniciando Seu Sistema Automaticamente no Boot

A forma como o Linux inicia (e para) todos os seus subsistemas é muito simples e modular. Permite definir ordem de inicialização, níveis (runlevels) etc.

9.1. Da BIOS aos Subsistemas

Vamos repassar brevemente o que acontece quando bootamos o Linux.

  1. A BIOS ou o bootloader (lilo, zlilo, grub, etc) carregam o Kernel do Linux do disco para a memória, com alguns parâmetros definidos na configuração do bootloader. Isso é percebido pela série de pontos que aparecem na tela. O arquivo do Kernel fica no diretório /boot, e só é acessado neste instante.

  2. Já na memória, o código do Kernel começa a rodar, detectando uma série de dispositivos essenciais, partições dos discos, etc.

  3. Uma das últimas coisas que o Kernel faz é montar o filesystem / (raiz), que obrigatoriamente deve conter as pastas /etc, /sbin, /bin e /lib.

  4. Imediatamente após, chama o programa init (/sbin/init) e passa o controle para ele.

  5. O init irá ler seu arquivo de configuração (/etc/inittab) que define o runlevel do sistema, e alguns script em Shell a serem rodados.

  6. Esses scripts continuam a preparação da infraestrutura mínima do sistema, montando os outros filesystems (de acordo com /etc/fstab), ativando a área de transferência (memória virtual), etc.

  7. O último passo, e o que mais deve lhe interessar, é a execução do script especial /etc/rc.d/rc, que inicia os subsistemas de acordo com uma estrutura de diretórios que está sob /etc/rc.d. O nome rc vem de run commands.

9.2. Runlevels

O mecanismo de runlevels permite fazer o Linux se iniciar de formas diferentes. E permitem também mudarmos de um perfil (runlevel) para outro sem rebootarmos.

O runlevel default é definido na /etc/inittab com uma linha do tipo

Exemplo 3. Linha do runlevel default em /etc/inittab

id:3:initdefault:

Os runlevels são números de 0 a 6, e cada um deles é usado de acordo com o seguinte padrão:

0

Para o sistema. Entrando neste runlevel, todos os subsistemas serão desativados suavemente antes da parada. Não use isso na linha initdefault da /etc/inittab.

1

Modo mono-usuário. Somente subsistemas vitais são iniciados pois é usado para fazer manutenções no sistema. Neste runlevel não é exigido um login de usuário, ao invés disso, é diretamente fornecida uma linha de comando para o usuário.

3, 2,

O 3 é usado quando uma máquina está em pleno funcionamento. Pense que este é o runlevel em que seu Software vai rodar. O 2 é histórico e é como o 3 porém sem NFS.

4

Não é usado. Você pode defini-lo como quiser, apesar de ser incomum.

5

Como o 3 mais um login gráfico. É ideal para uma estação de trabalho desktop. Use o 3 no caso da máquina ser um servidor, por questões de segurança e performance.

6

Como o runlevel 0, porém após a parada a máquina é reiniciada. Não use isso na linha initdefault da /etc/inittab.

Pode-se mudar de um runlevel para outro com o comando telinit. E pode-se ver o runlevel corrente e o anterior com o comando runlevel. Veja abaixo como mudamos do runlevel 3 para o 5.

bash# runlevel
N 3
bash# telinit 5
bash# runlevel
3 5
bash# 

9.3. Os Subsistemas

Podemos citar como exemplo de subsistemas um web-server, um banco de dados, ou ainda a camada de rede do SO. Não consideraremos como sendo subsistema uma aplicação totalmente voltada ao usuário (como um editor de textos).

O Linux provê uma forma elegante e modular para organizar a inicialização dos subistemas. Um fator importante é pensar nas dependências entre eles. Por exemplo, não faz sentido iniciar um web-server antes do subsistema de rede estar ativo.

Os subsistemas se organizam sob os diretórios /etc/init.d e /etc/rc.d/rcN.d:

/etc/init.d

Todos os Subsistemas instalados colocam neste diretorio um programa de controle, que é um script que segue um padrão simples descrito adiante. Esta é um listagem simplificada deste diretório:

Exemplo 4. Subsistemas instalados em /etc/init.d

bash:/etc/init.d# ls -l
-rwxr-xr-x  1 root  root   9284 Aug 13  2001 functions
-rwxr-xr-x  1 root  root   4984 Sep  5 00:18 halt
-rwxr-xr-x  1 root  root   5528 Nov  5 09:44 firewall
-rwxr-xr-x  1 root  root   1277 Sep  5 21:09 keytable
-rwxr-xr-x  1 root  root    487 Jan 30  2001 killall
-rwxr-xr-x  1 root  root   7958 Aug 15 17:20 network
-rwxr-xr-x  1 root  root   1490 Sep  5 07:54 ntpd
-rwxr-xr-x  1 root  root   2295 Jan 30  2001 rawdevices
-rwxr-xr-x  1 root  root   1830 Aug 31 09:29 httpd
-rwxr-xr-x  1 root  root   1311 Aug 15 14:18 syslog
/etc/rc.d/rcN.d (N é o indicador do runlevel)

Estes diretórios (cada runlevel tem um) devem conter somente links simbólicos especiais aos scripts em /etc/init.d. é assim que eles parecem:

Exemplo 5. Listagem de /etc/rc3.d

bash:/etc/rc3.d# ls -l
lrwxrwxrwx  1 root  root     18 Jan 14 11:59 K92firewall -> ../init.d/firewall
lrwxrwxrwx  1 root  root     17 Jan 14 11:59 S10network -> ../init.d/network
lrwxrwxrwx  1 root  root     16 Jan 14 11:59 S12syslog -> ../init.d/syslog
lrwxrwxrwx  1 root  root     18 Jan 14 11:59 S17keytable -> ../init.d/keytable
lrwxrwxrwx  1 root  root     20 Jan 14 11:59 S56rawdevices -> ../init.d/rawdevices
lrwxrwxrwx  1 root  root     16 Jan 14 11:59 S56xinetd -> ../init.d/xinetd
lrwxrwxrwx  1 root  root     18 Jan 14 11:59 S75httpd -> ../init.d/httpd
lrwxrwxrwx  1 root  root     11 Jan 13 21:45 S99local -> ../rc.local

Veja como todos os links tem um prefixo começando com a letra K (de Kill, para desativar) ou S (de Start, para ativar), e um número de 2 dígitos que definem a prioridade de ativação no boot. Em nosso exemplo temos HTTPd (prioridade 75) iniciando depois do subsistema de Rede (prioridade 10). E o subsistema de Firewalling será desativado (K) neste runlevel.

Portanto, para fazer seu Software iniciar automaticamente no boot, ele deve ser um subsistema, e veremos como fazer isso em seguinda.

9.4. Fazendo seu Software Ser um Subsistema

Os arquivos de seu Software se espalharão pelo SO, mas você vai querer prover uma interface simples e consistente para que o usuário possa principalmente inicia-lo e para-lo. A arquitetura de Subsistemas promove esta facilidade permitindo-lhe também (não obrigatoriamente) ser automático no boot. Basta colocar um script em /etc/init.d que siga um padrão para que seja funcional e prático.

Exemplo 6. Esqueleto de um script de Subsistema em /etc/init.d

#!/bin/sh
#
# /etc/init.d/mysystem
# Subsystem file for "MySystem" server
#
# chkconfig: 2345 95 05	1
# description: MySystem server daemon
#
# processname: MySystem
# config: /etc/MySystem/mySystem.conf
# config: /etc/sysconfig/mySystem
# pidfile: /var/run/MySystem.pid

# source function library
. /etc/rc.d/init.d/functions

# pull in sysconfig settings
[ -f /etc/sysconfig/mySystem ] && . /etc/sysconfig/mySystem	2

RETVAL=0
prog="MySystem"
.
.	3
.

start() {	4
	echo -n $"Starting $prog:"
	.
	.	5
	.
	RETVAL=$?
	[ "$RETVAL" = 0 ] && touch /var/lock/subsys/$prog
	echo
}

stop() {	6
	echo -n $"Stopping $prog:"
	.
	.	7
	.
	killproc $prog -TERM
	RETVAL=$?
	[ "$RETVAL" = 0 ] && rm -f /var/lock/subsys/$prog
	echo
}

reload() {	8
	echo -n $"Reloading $prog:"
	killproc $prog -HUP
	RETVAL=$?
	echo
}

case "$1" in	9
	start)
		start
		;;
	stop)
		stop
		;;
	restart)
		stop
		start
		;;
	reload)
		reload
		;;
	condrestart)
		if [ -f /var/lock/subsys/$prog ] ; then
			stop
			# avoid race
			sleep 3
			start
		fi
		;;
	status)
		status $prog
		RETVAL=$?
		;;
	*)	10
		echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}"
		RETVAL=1
esac
exit $RETVAL
1

Apesar de serem comentários, são usados pelo comando chkconfig e devem estar presentes. Esta linha em particular define que nos runlevels 2,3,4 e 5, este subsistema deve ser ativado com prioridade 95 (um dos últimos), e desativado com prioridade 05 (um dos primeiros).

2

Além da própria configuração de seu Software, este script pode ter um arquivo de configuração. O local padrão para isso é sob o diretório /etc/sysconfig, e no nosso caso vamos chama-lo de mySystem. Esta linha de código lê esse arquivo de configuração.

4 6 8

Seu script pode ter várias funções, mas é obrigatório que implemente start e stop, pois são elas que iniciam e param seu Software no boot. Outros métodos podem ser chamadas a partir de opções da linha de comando, e você pode definir quantos quiser.

9

Após definidas as ações do script, a linha de comando é analisada e o método (ação) correto é chamado.

10

Se este script for executado sem nenhum parâmetro, retornará uma mensagem de ajuda como a seguinte:

bash# /etc/init.d/mysystem
Usage: mysystem {start|stop|restart|reload|condrestart|status}
3 5 7

Aqui vão comandos específicos de seu Software.

Os metodos que você implementou no subsistema mysystem poderão ser invocados pelos usuários com o comando service, como no exemplo:

Exemplo 7. Usando o comando service

bash# service mysystem start
Starting MySystem:			[ OK ]
bash# service mysystem status
Subsysten MySystem is active with pid 1234
bash# service mysystem reload
Reloading MySystem:			[ OK ]
bash# service mysystem stop
Stopping MySystem:			[ OK ]
bash# 

Você não precisa se preocupar em gerenciar os links simbólicos em /etc/rc.d/rcN.d. O commando chkconfig faz isso para você, baseado nos comentários de controle definidos no começo de sue script.

Exemplo 8. Usando o comando chkconfig

bash# chkconfig --add mysystem
bash# chkconfig --del mysystem

Leia o manual do chkconfig para ver o que mais ele pode fazer por você.

9.5. Empacotando seu Script

Quando criar o RPM, coloque seu script de Subsistema em /etc/init.d e não inclua nenhum link nos diretórios /etc/rc.d/rcN.d, porque é uma decisão do usuário permitir seu Subsistema ser automático ou não. Se os links forem incluidos no pacote, e o usuário faz alguma mudança, o inventário de arquivos do RPM se tornará incosistente.

Os links simbólicos devem ser criados e removidos dinamicamente pelo processo de pós instalação e pré-desintalação de seu pacote, usando o comando chkconfig. Esta abordagem garente 100% de consistência para o pacote e sistema de arquivos.

A. Red Hat, Sobre a Estrutura do Filesystem

Este texto foi tirado de The Official Red Hat Linux Reference Guide

Por que Compartilhar uma Estrutura Comum?

A estrutura do filesystem de um SO é o nível mais básico de organização. Quase todas as formas em que o SO interage com seus usuários, aplicações, e modelo de segurança são dependentes na forma ele armazena seus arquivos num dispositivo primário de armazenamento (geralmente um HD). é crucial, por uma variedade de razões que usuários, como também programas no momento da instalação e além, sejam capazes de se referir a uma diretiva comum para saber onde ler e escrever seus binários, configurações, logs, e outros arquivos necessários.

Um organização do filesystem pode ser vista em termos de duas diferentes categorias lógicas de arquivos:

  1. Arquivos compartilhaveis versus não-compartilhaveis

  2. Arquivos variáveis versus estáticos

Arquivos compartilhaveis são aqueles que podem ser acessados por várias máquinas; não-compartilhaveis não estão disponíveis para nenhuma outra máquina. Arquivos variáveis podem mudar a qualquer momento sem a intervenção (ativa ou passiva) do administrador do sistema; arquivos estáticos, como documentação e binários, não mudam sem uma ação do administrador do sistema, ou um agente que o administrador ativou para efetuar esta tarefa.

A razão para olhar para os arquivos desta maneira tem a ver com o tipo de permissão dado ao diretório que os contém. O modo como o SO e seus usuários precisam utilizar os arquivos determina o diretório onde esses arquivos devem ser colocados, tanto para diretórios que foram montados somente-para-leitura ou leitura-e-escrita, e o nível de acesso permitido em cada arquivo. O nível mais externo desta organização (diretório /) é crucial, como o accesso aos seus diretórios mais internos podem ser restringidos, ou problemas de segurança podem se manifestar, se o alto nível é deixado desorganizado (segurança=organização), ou sem uma estrutura amplamente utilizada.

Contudo, simplesmente tendo uma estrutura não significa muito, a não ser que seja um padrão. Estruturas concorrentes podem na verdade causar mais problemas do que soluções. Por isso, a Red Hat escolheu a estrutura de filesystem mais amplamente usada, e a extendeu ligeiramente para acomodar arquivos especiais usados no Red Hat Linux.

B. Sobre este Documento

Este documento deve ser distribuido sob a GNU Free Documentation License, o que o torna suficientemente livre. Todos estão convidados a contribuir com seu conteúdo e idéias.

Copyright 2002, de Avi Alkalay.

Este documento está publicado nos seguintes lugares:

Foi escrito originalmente em português do Brasil, e depois traduzido para o inglês. Foi usado SGML e o mais-que-incrivel DocBook, que permitiu disponibiliza-lo em outros formatos, encontrados no site.

Ficou pronto (português+inglês) em meados de março de 2002. Qualquer mudança após esta época, é perfumaria.

Eu o escrevi para ajudar companhias comercias e desenvolvedores OpenSource a fazer software plug-and-play, fácil de usar para Linux, e assim melhorar sua usabilidade e popularidade.

Todos os conceitos (de uma forma abrangente) descritos aqui podem ser aplicados em qualquer outro UNIX, ou outro sistema opracional também, inclusive Windows. Talvez um dia eu escreva um desses para Windows...ou Mac....