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).
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.
Imagine que você vai instalar aquele produto caríssimo que sua empresa comprou da ACME, e descobre que terá de fazer o seguinte:
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ê
Ler arquivos README
Descompactar no disco enormes arquivos (depois de baixa-los da rede ou do CD), para criar o ambiente de instalação
Ler mais arquivos README que surgiram na descompactação
Entender que para instalar terá que executar de uma forma especial algum script fornecido (o inconveniente ./install.sh)
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
Configurar variáveis de ambiente em sua profile, tais como $PATH, $LIBPATH, $ACMEPROGRAM_DATA_DIR, $ACMEPROGRAM_BIN_DIR, etc
Editar arquivos do sistema para incluir a presença do novo produto (ex: /etc/inetd.conf, /etc/inittab)
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:
Compreendendo as Quatro Partes Universais de Qualquer Software
Entendendo como eles se relacionam com a hierarquia de diretórios do Linux
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
O conjunto de arquivos de qualquer Software, seja ele gráfico, de servidor, comercial, aberto/livre, monolítico etc, tem sempre 4 partes universais:
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.
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.
é 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.
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.
Vamos ver a universalidade do conceito acima analizando alguns tipos aleatórios de softwares:
Tabela 1. Universalidade das 4 Partes
Software em Sí | Configurações | Conteúdo | Logs, Dumps etc | |
---|---|---|---|---|
Servidor de Banco de Dados | Biná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 Textos | Idem, templates, filtros modulares de formatos, etc | Sendo 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, etc | Os documentos gerados pelo usuário, geralmente em algum lugar de seu $HOME | Aparecem 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 MP3 | Idem, filtros modulares de audio | Cada usuário tem o seu no $HOME, e contém preferências de bitrate etc | Semelhante ao do Editor de Textos | Semelhante ao do Editor de Textos |
Web Server | Idem | Arquivos que definem os diretórios do Conteúdo, parâmetros de rede e performance, segurança, etc | Diretórios em que o webmaster deposita sua criatividade. Localização novamente definida pelas Configurações | Preciosos 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-mail | Idem | Arquivos que definem como acessar base de dados de usuários, regras de roteamento de mensagens, etc | As preciosas caixas postais dos usuários. Localização definida pelas Configurações | Log 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.
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:
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
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
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
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
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 # Minimal content directories MIN_CONTENT_PATH=/var/www:/var/MySoftware/www if [ -r "$CONF"]; then . "$CONF" 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 . . .
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 # Your e-mail address, for notifications. EMAIL=john@mycompany.com # Logs directory LOG_DIR=/var/log/myInstance
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?
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:
O FHS é um padrão, e padrões são vitais
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
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
Então vamos resumir o que o FHS diz sobre as pastas (diretórios) do Linux:
As Pastas do Linux
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.
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.
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.
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.
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.
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.
Contém os arquivos de configuração. Se seu Software tem vários, coloque-os numa subpasta chamada /etc/meuproduto/
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.
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.
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.
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.
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ções | Conteúdo | Logs, 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 |
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:
Força o usuário a alterar variáveis de ambiente como $PATH e $LD_LIBRARY_PATH para usar seu produto.
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.
O administrador do sistema provavelmente não alocou espaço em disco para estas partições, causando transtornos no tempo de instalação.
É 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...
...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.
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. |
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.
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.
Isso é extremamente importante por vários motivos:
Facilidade ao usuário. Este é sempre o motivo primordial.
Automatiza algumas tarefas que devem ser feitas antes e depois de instalar seu Software. Novamente trazendo facilidade.
Gerencia inteligentemente arquivos de configuração, documentação etc, dando mais controle num upgrade.
Gerencia interdependências com outros pacotes e versões, garantindo bom funcionamento.
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.
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:
O livro Maximum RPM, também disponível on-line e em PostScript.
RPM-HOWTO que é bem mais curto e direto
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:
MyDB-common-1.0-3.i386.rpm
MyDB-server-1.0-3.i386.rpm
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á:
MyDB-common-1.0-3.i386.rpm
MyDB-client-1.0-3.i386.rpm
E se o perfil for de servidor:
MyDB-common-1.0-3.i386.rpm
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.
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).
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.
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.
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.
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:
Coletar dados de quais módulos instalar, percebidos pelo usuário como checkboxes.
Coletar dados necessários para criar uma configuração (a alma) inicial para seu Software.
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.
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.
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.
Vamos repassar brevemente o que acontece quando bootamos o Linux.
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.
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.
Uma das últimas coisas que o Kernel faz é montar o filesystem / (raiz), que obrigatoriamente deve conter as pastas /etc, /sbin, /bin e /lib.
Imediatamente após, chama o programa init (/sbin/init) e passa o controle para ele.
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.
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.
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.
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
Os runlevels são números de 0 a 6, e cada um deles é usado de acordo com o seguinte padrão:
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.
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.
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.
Não é usado. Você pode defini-lo como quiser, apesar de ser incomum.
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.
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#
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:
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
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.
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 # 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 RETVAL=0 prog="MySystem" . . . start() { echo -n $"Starting $prog:" . . . RETVAL=$? [ "$RETVAL" = 0 ] && touch /var/lock/subsys/$prog echo } stop() { echo -n $"Stopping $prog:" . . . killproc $prog -TERM RETVAL=$? [ "$RETVAL" = 0 ] && rm -f /var/lock/subsys/$prog echo } reload() { echo -n $"Reloading $prog:" killproc $prog -HUP RETVAL=$? echo } case "$1" in 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=$? ;; *) echo $"Usage: $0 {start|stop|restart|reload|condrestart|status}" RETVAL=1 esac exit $RETVAL
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). | |
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. | |
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. | |
Após definidas as ações do script, a linha de comando é analisada e o método (ação) correto é chamado. | |
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} | |
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.
Leia o manual do chkconfig para ver o que mais ele pode fazer por você.
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.
Este texto foi tirado de The Official Red Hat Linux Reference Guide
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:
Arquivos compartilhaveis versus não-compartilhaveis
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.
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:
Ensaio Linux and Main (24 de Março, 2002)
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....