Este capítulo oferece estudos de caso para mostrar exemplos de empacotamento tais como instalar objetos condicionalmente, determinar em tempo de execução quantos arquivos criar e modificar um arquivo de dados existente durante a instalação e a remoção do pacote.
Cada estudo de caso começa com uma descrição, seguida de uma lista das técnicas de empacotamento usadas, uma descrição narrativa da abordagem adotada ao usar tais técnicas e scripts e arquivos de amostra associados ao estudo de caso.
A lista abaixo traz os estudos de caso encontrados neste capítulo.
Criando um arquivo na instalação e salvando-o durante a remoção
Modificando um arquivo usando classes padrão e scripts de ação de classe
Modificando um arquivo usando a classe sed e um script postinstall
Instalando e removendo um driver com scripts de procedimento
Instalando um driver usando a classe sed e scripts de procedimento
O pacote deste estudo de caso possui três tipos de objetos. O administrador pode escolher qual dos três tipos instalar e onde colocar os objetos na máquina de instalação.
Este estudo de caso demonstra as seguintes técnicas:
Uso de nomes de caminho paramétricos (variáveis em nomes de caminho do objeto) usados para estabelecer vários diretórios base
Para obter informações sobre nomes de caminho paramétricos, consulte Nomes de caminho paramétrico.
Uso de um script request para solicitar entrada do administrador
Para obter informações sobre scripts request, consulte Escrevendo um script request.
Definição de valores condicionais para um parâmetro de instalação.
Para configurar a instalação seletiva neste estudo de caso, você deve concluir as seguintes tarefas:
Definir uma classe para cada tipo de objeto que pode ser instalado.
Neste estudo de caso, os três tipos de objetos são as executáveis do pacote, as páginas do manual e as executáveis emacs. Cada tipo possui sua própria classe: bin, man e emacs, respectivamente. Observe que no arquivo prototype todos os arquivos do objeto pertencem a uma dessas três classes.
Inicializar o parâmetro CLASSES no arquivo pkginfo como nulo.
Normalmente, quando uma classe é definida, ela deve ser listada no parâmetro CLASSES no arquivo pkginfo. Do contrário, nenhum objeto é instalado em tal classe. Para este estudo de caso, o parâmetro é inicialmente definido como nulo, o que significa que nenhum objeto será instalado. O parâmetro CLASSES será alterado pelo script request, com base nas escolhas do administrador. Desta forma, o parâmetro CLASSES é definido somente para os tipos de objetos que o administrador deseja instalar.
Em geral, é uma boa idéia definir os parâmetros com um valor padrão. Se este pacote tiver componentes comuns aos três tipos de objetos, você pode atribuí-los a classe none e, então, definir o parâmetro CLASSES igual a none.
Inserir nomes de caminho paramétricos no arquivo prototype.
O script request define estas variáveis de ambiente com o valor fornecido pelo administrador. Nesse caso, o comando pkgadd resolve estas variáveis de ambiente no tempo de instalação e sabe onde instalar o pacote.
As três variáveis de ambiente usadas deste exemplo estão definidas com seus valores padrão no arquivo pkginfo e servem para os seguintes propósitos:
$NCMPBIN define o local das executáveis do objeto
$NCMPMAN define o local das páginas do manual
$EMACS define o local das executáveis emacs
O arquivo prototype do exemplo mostra como definir os nomes de caminho do objeto com as variáveis.
Criar um script request para perguntar ao administrador que partes do pacote devem ser instaladas e onde devem ser colocadas.
O script request deste pacote faz duas perguntas ao administrador:
Esta parte do pacote deve ser instalada?
Quando a resposta for sim, o nome de classe apropriado é adicionado ao parâmetro CLASSES. Por exemplo, quando o administrador opta por instalar as páginas do manual associadas a este pacote, a classe man é adicionada ao parâmetro CLASSES.
Se afirmativo, onde esta parte deve ser colocada?
A variável de ambiente apropriada é definida de acordo com a resposta a esta pergunta. No exemplo da página do manual, a variável $NCMPMAN é definida como o valor da resposta.
Estas duas perguntas são repetidas em cada um dos três tipos de objetos.
No final do script request, os parâmetros são disponibilizados para o ambiente de instalação do comando pkgadd e qualquer outro script de empacotamento. O script request faz isso gravando estas definições no arquivo fornecido pelo utilitário de chamada. Para este estudo de caso, não é fornecido nenhum outro script.
Ao observar o script request deste estudo de caso, note que as perguntas são geradas pelas ferramentas de validação de dados ckyorn e ckpath. Para obter mais informações sobre estas ferramentas, consulte ckyorn(1) e ckpath(1).
PKG=ncmp NAME=NCMP Utilities CATEGORY=application, tools BASEDIR=/ ARCH=SPARC VERSION=RELEASE 1.0, Issue 1.0 CLASSES="" NCMPBIN=/bin NCMPMAN=/usr/man EMACS=/usr/emacs |
i pkginfo i request x bin $NCMPBIN 0755 root other f bin $NCMPBIN/dired=/usr/ncmp/bin/dired 0755 root other f bin $NCMPBIN/less=/usr/ncmp/bin/less 0755 root other f bin $NCMPBIN/ttype=/usr/ncmp/bin/ttype 0755 root other f emacs $NCMPBIN/emacs=/usr/ncmp/bin/emacs 0755 root other x emacs $EMACS 0755 root other f emacs $EMACS/ansii=/usr/ncmp/lib/emacs/macros/ansii 0644 root other f emacs $EMACS/box=/usr/ncmp/lib/emacs/macros/box 0644 root other f emacs $EMACS/crypt=/usr/ncmp/lib/emacs/macros/crypt 0644 root other f emacs $EMACS/draw=/usr/ncmp/lib/emacs/macros/draw 0644 root other f emacs $EMACS/mail=/usr/ncmp/lib/emacs/macros/mail 0644 root other f emacs $NCMPMAN/man1/emacs.1=/usr/ncmp/man/man1/emacs.1 0644 root other d man $NCMPMAN 0755 root other d man $NCMPMAN/man1 0755 root other f man $NCMPMAN/man1/dired.1=/usr/ncmp/man/man1/dired.1 0644 root other f man $NCMPMAN/man1/ttype.1=/usr/ncmp/man/man1/ttype.1 0644 root other f man $NCMPMAN/man1/less.1=/usr/ncmp/man/man1/less.1 0644 inixmr other |
trap 'exit 3' 15 # determine if and where general executables should be placed ans=`ckyorn -d y \ -p "Should executables included in this package be installed" ` || exit $? if [ "$ans" = y ] then CLASSES="$CLASSES bin" NCMPBIN=`ckpath -d /usr/ncmp/bin -aoy \ -p "Where should executables be installed" ` || exit $? fi # determine if emacs editor should be installed, and if it should # where should the associated macros be placed ans=`ckyorn -d y \ -p "Should emacs editor included in this package be installed" ` || exit $? if [ "$ans" = y ] then CLASSES="$CLASSES emacs" EMACS=`ckpath -d /usr/ncmp/lib/emacs -aoy \ -p "Where should emacs macros be installed" ` || exit $? fi |
Observe que um script request pode sair sem deixar nenhum arquivo no sistema de arquivos. Em instalações em versões do Solaris anteriores a 2.5 e versões compatíveis (onde nenhum script checkinstall pode ser usado), o script request é o lugar correto para testar o sistema de arquivos de todas as formas necessárias para garantir que a instalação será bem-sucedida. Quando o script request existir com o código 1, a instalação sairá perfeitamente.
Estes arquivos de exemplo mostram o uso de caminhos paramétricos para estabelecer vários diretórios base. No entanto, o método preferido envolve o uso do parâmetro BASEDIR que é gerenciado e validado pelo comando pkgadd. Sempre que vários diretórios base forem usados, tenha especial cuidado em prover a instalação de várias versões e arquiteturas na mesma plataforma.
Este estudo de caso cria um arquivo de banco de dados no tempo de instalação e salva um cópia do banco de dados quando o pacote é removido.
Este estudo de caso demonstra as seguintes técnicas:
Uso de classes e script de ação de classe para realizar ações especiais em diferentes conjuntos de objetos
Para obter informações, consulte Escrevendo scripts de ação de classe.
Uso do arquivo space para informar o comando pkgadd que é necessário espaço extra para instalar este pacote adequadamente
Para mais informações sobre o arquivo space, consulte Reservando espaço adicional em um sistema de destino.
Uso do comando installf para instalar um arquivo não definido nos arquivos prototype e pkgmap.
Para criar um arquivo de banco de dados na instalação e salvar uma cópia na remonação neste estudo de caso, você deve realizar as tarefas seguintes:
Definir três classes.
O pacote deste estudo de caso requer que as três classes seguintes sejam definidas no parâmetro CLASSES:
A classe none padrão, que contém um conjunto de processos pertencente ao subdiretório bin.
A classe admin, que contém um arquivo executável config e um diretório contendo arquivos de dados.
A classe cfgdata, que contém um diretório.
Tornar o pacote relocável coletivamente.
Observe que no arquivo prototype nenhum dos nomes de caminho começa com um barra ou uma variável de ambiente. Isso indica que são relocáveis coletivamente.
Calcular a quantidade de espaço que o arquivo de banco de dados necessita e criar um arquivo space para ser distribuído com o pacote. Este arquivo notifica o comando pkgadd que o pacote requer espaço extra e especifica quanto.
Criar um script de ação de classe para a classe admin (i.admin).
O script de amostra inicializa um banco de dados usando os arquivos de dados pertencentes à classe admin. Para realizar esta tarefa, ele adota o seguinte procedimento:
Copia o arquivo de dados de origem ao destino apropriado
Cria um arquivo vazio chamado config.data e o atribui a uma classe de cfgdata
Executa o comando bin/config (distribuido com o pacote e já instalado) para preencher o arquivo de banco de dados config.data usando os arquivos de dados pertencentes à classe admin
Executa o comando installf -f para finalizar a instalação de config.data
Não é necessário realizar nenhuma ação especial na classe admin no tempo de remoção já que nenhum script de ação de classe de remoção é criado. Isso significa que todos os arquivos e diretórios da classe admin são removidos do sistema.
Criar um script de ação de remoção para a classe cfgdata (r.cfgdata).
O script de remoção faz uma cópia do arquivo de banco de dados antes de excluí-lo. Não é necessário realizar nenhuma ação especial nesta classe no tempo de instalação, já que nenhum script de classe de instalação é necessário.
Lembre-se de que a entrada de um script de remoção é uma lista de nomes de caminho a serem removidos. Os nomes de caminho sempre aparecem na ordem alfabética inversa. Este script de remoção copia os arquivos em um diretório chamado $PKGSAV. Quando todos os nomes de caminho tiverem sido processados, o script volta e remove todos os diretórios e arquivos associados à classe cfgdata.
O resultado deste script de remoção é copiar config.data em $PKGSAV e, em seguida, remover o arquivo config.data e o diretório de dados.
PKG=krazy NAME=KrAzY Applications CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1 CLASSES=none cfgdata admin |
i pkginfo i request i i.admin i r.cfgdata d none bin 555 root sys f none bin/process1 555 root other f none bin/process2 555 root other f none bin/process3 555 root other f admin bin/config 500 root sys d admin cfg 555 root sys f admin cfg/datafile1 444 root sys f admin cfg/datafile2 444 root sys f admin cfg/datafile3 444 root sys f admin cfg/datafile4 444 root sys d cfgdata data 555 root sys |
# extra space required by config data which is # dynamically loaded onto the system data 500 1 |
# PKGINST parameter provided by installation service # BASEDIR parameter provided by installation service while read src dest do cp $src $dest || exit 2 done # if this is the last time this script will be executed # during the installation, do additional processing here. if [ "$1" = ENDOFCLASS ] then # our config process will create a data file based on any changes # made by installing files in this class; make sure the data file # is in class `cfgdata' so special rules can apply to it during # package removal. installf -c cfgdata $PKGINST $BASEDIR/data/config.data f 444 root sys || exit 2 $BASEDIR/bin/config > $BASEDIR/data/config.data || exit 2 installf -f -c cfgdata $PKGINST || exit 2 fi exit 0 |
Isso ilustra uma instância rara na qual installf é apropriada em um script de ação de classe. Pelo fato do arquivo space ser usado para reservar espaço em um sistema de arquivos específico, este novo arquivo pode ser adicionado seguramente, mesmo se não estiver incluído no arquivo pkgmap.
# the product manager for this package has suggested that # the configuration data is so valuable that it should be # backed up to $PKGSAV before it is removed! while read path do # path names appear in reverse lexical order. mv $path $PKGSAV || exit 2 rm -f $path || exit 2 done exit 0 |
O pacote deste estudo de caso usa arquivos de informação opcionais para definir as compatibilidades e dependências do pacote, e para apresentar uma mensagem de copyright durante a instalação.
Este estudo de caso demonstra as seguintes técnicas:
Uso do arquivo copyright
Uso do arquivo compver
Uso do arquivo depend
Para obter mais informações sobre estes arquivos, consulte Criando arquivos de informação.
Para satisfazer os requisitos da descrição, você deve:
Criar um arquivo copyright.
Um arquivo copyright contém o texto ASCII de uma mensagem de copyright. A mensagem que aparece no arquivo de amostra é exibida na tela durante a instalação do pacote.
Criar um arquivo compver.
O arquivo pkginfo que aparece na ilustração seguinte define a versão deste pacote como versão 3.0. O arquivo compver define que a versão 3.0 é compatível com as versões 2.3, 2.2, 2.1, 2.1.1, 2.1.3 e 1.7.
Criar um arquivo depend.
Os arquivos listados em um arquivo depend já devem estar instalados no sistema quando um pacote for instalado. O arquivo de exemplo possui 11 pacotes que já devem estar no sistema no momento da instalação.
PKG=case3 NAME=Case Study #3 CATEGORY=application BASEDIR=/opt ARCH=SPARC VERSION=Version 3.0 CLASSES=none |
Copyright (c) 1999 company_name All Rights Reserved. THIS PACKAGE CONTAINS UNPUBLISHED PROPRIETARY SOURCE CODE OF company_name. The copyright notice above does not evidence any actual or intended publication of such source code |
Version 3.0 Version 2.3 Version 2.2 Version 2.1 Version 2.1.1 Version 2.1.3 Version 1.7 |
P acu Advanced C Utilities Issue 4 Version 1 P cc C Programming Language Issue 4 Version 1 P dfm Directory and File Management Utilities P ed Editing Utilities P esg Extended Software Generation Utilities Issue 4 Version 1 P graph Graphics Utilities P rfs Remote File Sharing Utilities Issue 1 Version 1 P rx Remote Execution Utilities P sgs Software Generation Utilities Issue 4 Version 1 P shell Shell Programming Utilities P sys System Header Files Release 3.1 |
Este estudo de caso modifica um arquivo existente durante a instalação do pacote usando classes padrão e scripts de ação de classe. Usa um dos três métodos de modificação. Os outros dois métodos estão descritos em Modificando um arquivo usando a classe sed e um script postinstall e Modificando um arquivo usando a classe build. O arquivo modificado é /etc/inittab .
Este estudo de caso demonstra como usar os scripts de ação de classe de instalação e de remoção. Para obter informações, consulte Escrevendo scripts de ação de classe.
Para modificar /etc/inittab durante a instalação usando classes e scripts de ação de classe, você deve realizar as tarefas seguintes:
Criar uma classe.
Crie uma classe chamada inittab . Você deve fornecer um script de ação de classe de instalação e um de remoção para esta classe. Defina a classe inittab no parâmetro CLASSES no arquivo pkginfo.
Criar um arquivo inittab.
Este arquivo contém a informação da entrada que você adicionará ao /etc/inittab . Observe que no arquivo prototype aparece que inittab é um membro da classe inittab e possui um tipo de arquivo de e para editável.
Criar um script de ação de classe de instalação (i.inittab).
Lembre-se que os scripts de ação de classe devem produzir os mesmos resultados sempre que forem executados. O script de ação de classe realiza os seguintes procedimentos:
Verifica se esta entrada tinha sido adicionada anteriormente
Se tiver sido, remove as versões anteriores da entrada
Edita o arquivo inittab e adiciona as linhas de comentário para que você saiba de onde é a entrada
Move o arquivo temporário de volta para /etc/inittab
Executa o comando init q quando recebe o indicador ENDOFCLASS
Observe que o comando init q pode ser realizado por este script de instalação. Um script postinstall de uma linha não é necessário nesta abordagem.
Criar um script de ação de classe de remoção (r.inittab).
O script de remoção é muito parecido ao script de instalação. A informação adicionada pelo script de instalação é removida e o comando init q é executado.
Este estudo de caso é mais complicado do que o estudo de caso a seguir, consulte Modificando um arquivo usando a classe sed e um script postinstall. Em vez de fornecer dois arquivos, são necessários três arquivos e o arquivo /etc/inittab integrado é, em realidade, apenas um espaço reservado contendo um fragmento da entrada que será inserida. Poderia ter sido colocado no arquivo i.inittab exceto que o comando pkgadd deve ter um arquivo para passar ao arquivo i.inittab. O procedimento de remoção também deve ser colocado em outro arquivo (r.inittab). Embora este método funcione bem, é melhor reservá-lo para os casos que envolvam instalações complicadas de vários arquivos. Consulte Modificando arquivos crontab durante a instalação.
O programa sed usado em Modificando um arquivo usando a classe sed e um script postinstall oferece suporte a várias instâncias de pacote desde que o comentário no final da entrada inittab esteja baseado em uma instância de pacote. O estudo de caso em Modificando um arquivo usando a classe build mostra uma abordagem mais dinâmica para editar /etc/inittab durante a instalação.
PKG=case5 NAME=Case Study #5 CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1d05 CLASSES=inittab |
i pkginfo i i.inittab i r.inittab e inittab /etc/inittab ? ? ? |
# PKGINST parameter provided by installation service while read src dest do # remove all entries from the table that # associated with this PKGINST sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" $dest > /tmp/$$itab || exit 2 sed -e "s/$/#$PKGINST" $src >> /tmp/$$itab || exit 2 mv /tmp/$$itab $dest || exit 2 done if [ "$1" = ENDOFCLASS ] then /sbin/init q || exit 2 fi exit 0 |
# PKGINST parameter provided by installation service while read src dest do # remove all entries from the table that # are associated with this PKGINST sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" $dest > /tmp/$$itab || exit 2 mv /tmp/$$itab $dest || exit 2 done /sbin/init q || exit 2 exit 0 |
rb:023456:wait:/usr/robot/bin/setup |
Este estudo de caso modifica um arquivo que existe na máquina de instalação durante a instalação do pacote. Usa um dos três métodos de modificação. Os outros dois métodos estão descritos em Modificando um arquivo usando classes padrão e scripts de ação de classe e Modificando um arquivo usando a classe build. O arquivo modificado é /etc/inittab.
Este estudo de caso demonstra as seguintes técnicas:
Uso da classe sed
Para obter mais informações sobre a classe sed, consulte O script de classe sed.
Uso de um script postinstall
Para obter mais informações sobre este script, consulte Escrevendo scripts de procedimento.
Para modificar /etc/inittab no momento da instalação usando a classe sed, você deve realizar as tarefas seguintes:
Adicionar o script de classe sed ao arquivo prototype.
O nome de um script deve ser o nome do arquivo que será editado. Neste caso, o arquivo a ser editado é /etc/inittab e o script sed também é nomeado /etc/inittab. Não há requisitos de modo, proprietário e grupo de um script sed (representado no prototype de amostra por pontos de interrogação). O tipo de arquivo do script sed deve ser e (indicando que é editável).
Definir o parâmetro CLASSES para incluir a classe sed.
Conforme mostrado no arquivo de exemplo, sed é a única classe instalada. No entanto, poderia ser uma entre várias classes.
Criar um script de ação de classe sed.
Seu pacote não pode distribuir uma cópia de /etc/inittab que tenha a aparência que você precisa, já que /etc/inittab é um arquivo dinâmico e você não tem como saber como será sua aparência no momento da instalação do pacote. No entanto, o uso do script sed permitirá modificar o arquivo /etc/inittab durante a instalação do pacote.
Criar um script postinstall.
Você precisa executar o comando init q para informar o sistema que /etc/inittab foi modificado. O único lugar no qual você pode realizar esta ação neste exemplo é em um script postinstall. Ao observar o script postinstall de exemplo, você verá que o propósito dele é executar o comando init q.
Esta abordagem de edição de /etc/inittab durante a instalação tem uma desvantagem. Você tem que distribuir um script completo (o script postinstall) simplesmente para realizar o comando init q.
PKG=case4 NAME=Case Study #4 CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1d05 CLASSES=sed |
i pkginfo i postinstall e sed /etc/inittab ? ? ? |
!remove # remove all entries from the table that are associated # with this package, though not necessarily just # with this package instance /^[^:]*:[^:]*:[^:]*:[^#]*#ROBOT$/d !install # remove any previous entry added to the table # for this particular change /^[^:]*:[^:]*:[^:]*:[^#]*#ROBOT$/d # add the needed entry at the end of the table; # sed(1) does not properly interpret the '$a' # construct if you previously deleted the last # line, so the command # $a\ # rb:023456:wait:/usr/robot/bin/setup #ROBOT # will not work here if the file already contained # the modification. Instead, you will settle for # inserting the entry before the last line! $i\ rb:023456:wait:/usr/robot/bin/setup #ROBOT |
# make init re-read inittab /sbin/init q || exit 2 exit 0 |
Este estudo de caso modifica um arquivo que existe na máquina de instalação durante a instalação do pacote. Usa um dos três métodos de modificação. Os outros dois métodos estão descritos em Modificando um arquivo usando classes padrão e scripts de ação de classe e Modificando um arquivo usando a classe sed e um script postinstall. O arquivo modificado é /etc/inittab.
Este estudo de caso demonstra como usar a classe build. Para obter mais informações sobre a classe build, consulte O script de classe build.
Esta abordagem de modificação de /etc/inittab usa a classe build. Um script de classe build é executado com um script shell e sua saída se torna a nova versão do arquivo que está sendo executado. Em outras palavras, o arquivo de dados /etc/inittab distribuído com este pacote será executado e a saída de tal execução será /etc/inittab.
O script de classe build é executado durante a instalação e a remoção do pacote. O argumento install é passado para o arquivo se ele estiver sendo executado no tempo de instalação. Observe no script de classe build de amostra que as ações de instalação são definidas ao testar este argumento.
Para editar /etc/inittab usando a classe build, você deve realizar as tarefas seguintes:
Definir o arquivo build no arquivo prototype.
A entrada do arquivo build no arquivo prototype deve colocá-lo na classe build e definir seu tipo de arquivo como e. Certifique-se de que o parâmetro CLASSES do arquivo pkginfo esteja definido como build.
Criar o script de classe build.
O script de classe build de amostra realiza os seguintes procedimentos:
Edita o arquivo /etc/inittab para remover as alterações existentes deste pacote. Observe que o nome do arquivo /etc/inittab está definido de modo determinado e inalterável no comando sed.
Se o pacote estiver sendo instalado, adiciona a nova linha ao final de /etc/inittab. Uma marca de comentário é incluída na nova entrada para descrever de onde tal entrada provém.
Executa o comando init q.
Esta solução trata das desvantagens descritas nos estudos de caso em Modificando um arquivo usando classes padrão e scripts de ação de classe e em Modificando um arquivo usando a classe sed e um script postinstall. É necessário somente um arquivo breve (além dos arquivos pkginfo e prototype). O arquivo funciona com várias instâncias de um pacote desde que o parâmetro PKGINST seja usado, e o script postinstall não é necessário desde que o comando init q possa ser executado da classe build.
PKG=case6 NAME=Case Study #6 CATEGORY=applications BASEDIR=/opt ARCH=SPARC VERSION=Version 1d05 CLASSES=build |
i pkginfo e build /etc/inittab ? ? ? |
# PKGINST parameter provided by installation service # remove all entries from the existing table that # are associated with this PKGINST sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" /etc/inittab || exit 2 if [ "$1" = install ] then # add the following entry to the table echo "rb:023456:wait:/usr/robot/bin/setup #$PKGINST" || exit 2 fi /sbin/init q || exit 2 exit 0 |
Este estudo de caso modifica arquivos crontab durante a instalação do pacote.
Este estudo de caso demonstra as seguintes técnicas:
Uso de classes e scripts de ação de classe
Para obter informações, consulte Escrevendo scripts de ação de classe.
Uso do comando crontab dentro de um script de ação de classe.
A forma mais eficiente de editar mais de um arquivo durante a instalação é definir uma classe e fornecer um script de ação de classe. Se você usou a abordagem da classe build, será necessário distribuir um script de classe build para cada arquivo crontab editado. A definição de uma classe cron proporciona uma abordagem mais geral. Para editar arquivos crontab com esta abordagem, você deve:
Definir os arquivos crontab que serão editados no arquivo prototype.
Criar uma entrada no arquivo prototype para o arquivo crontab que será editado. Definir a classe como cron e o tipo de arquivo como e de cada arquivo. Usar o nome real do arquivo a ser editado.
Criar os arquivos crontab no pacote.
Estes arquivos contêm as informações que você deseja adicionar aos arquivos crontab existentes de mesmo nome.
Criar um script de ação de classe de instalação para a classe cron.
O script i.cron de amostra realiza os seguintes procedimentos:
Determina o ID de usuário (UID).
O script i.cron define a variável user como o nome base do script de classe cron que está sendo processado. Tal nome é o UID. Por exemplo, o nome base de /var/spool/cron/crontabs/root é root, que também é o UID.
Executa o crontab usando o UID e a opção - l.
A opção -l diz ao crontab para enviar o conteúdo do arquivo crontab do usuário definido para a saída padrão.
Conduz a saída do comando crontab ao script sed que remove as entradas adicionadas anteriormente com esta técnica de instalação.
Coloca a saída editada em um arquivo temporário.
Adiciona o arquivo de dados do UID root (distribuído com o pacote) ao arquivo temporário e adiciona uma marca para que você saiba de onde provêm estas entradas.
Executa o crontab com o mesmo UID e o fornece ao arquivo temporário como entrada.
Criar um script de ação de classe de remoção cron.
O script r.cron é semelhante ao script de instalação, exceto que não há nenhum procedimento para adicionar informações ao arquivo crontab.
Estes procedimentos são realizados por todos os arquivos na classe cron.
Os scripts i.cron e r.cron descritos abaixo são executados pelo superusuário. A edição de outro arquivo crontab do usuário como superusuário pode ter conseqüências imprevisíveis. Se necessário, altere a seguinte entrada em cada script de:
crontab $user < /tmp/$$crontab ||
para
su $user -c "crontab /tmp/$$crontab" ||
PKG=case7 NAME=Case Study #7 CATEGORY=application BASEDIR=/opt ARCH=SPARC VERSION=Version 1.0 CLASSES=cron |
i pkginfo i i.cron i r.cron e cron /var/spool/cron/crontabs/root ? ? ? e cron /var/spool/cron/crontabs/sys ? ? ? |
# PKGINST parameter provided by installation service while read src dest do user=`basename $dest` || exit 2 (crontab -l $user | sed -e "/#$PKGINST$/d" > /tmp/$$crontab) || exit 2 sed -e "s/$/#$PKGINST/" $src >> /tmp/$$crontab || exit 2 crontab $user < /tmp/$$crontab || exit 2 rm -f /tmp/$$crontab done exit 0 |
# PKGINST parameter provided by installation service while read path do user=`basename $path` || exit 2 (crontab -l $user | sed -e "/#$PKGINST$/d" > /tmp/$$crontab) || exit 2 crontab $user < /tmp/$$crontab || exit 2 rm -f /tmp/$$crontab done exit |
41,1,21 * * * * /usr/lib/uucp/uudemon.hour > /dev/null 45 23 * * * ulimit 5000; /usr/bin/su uucp -c "/usr/lib/uucp/uudemon.cleanup" > /dev/null 2>&1 11,31,51 * * * * /usr/lib/uucp/uudemon.poll > /dev/null |
0 * * * 0-6 /usr/lib/sa/sa1 20,40 8-17 * * 1-5 /usr/lib/sa/sa1 5 18 * * 1-5 /usr/lib/sa/sa2 -s 8:00 -e 18:01 -i 1200 -A |
Se a edição de um grupo de arquivos for aumentar o tamanho total do arquivo em mais de 10K, forneça um arquivo space para que o comando pkgadd possa permitir esse aumento. Para mais informações sobre o arquivo space, consulte Reservando espaço adicional em um sistema de destino.
Este pacote instala um driver.
Este estudo de caso demonstra as seguintes técnicas:
Instalação e carregamento de um driver com um script postinstall
Carregamento de um driver com um script preremove
Para obter mais informações sobre estes scripts, consulte Escrevendo scripts de procedimento.
Criar um script request.
O script request determina onde o administrador quer que os objetos de driver sejam instalados, perguntando ao administrador e atribuindo as respostas ao parâmetro $KERNDIR.
O script termina com uma rotina para tornar os dois parâmetros CLASSES e KERNDIR disponíveis para o ambiente de instalação e o script postinstall.
Criar um script postinstall.
O script postinstall realiza, na verdade, a instalação do driver. Ele é executado depois que os arquivos buffer e buffer.conf tiverem sido instalados. O arquivo postinstall mostrado neste exemplo realiza as seguintes ações:
Usa o comando add_drv para carregar o driver no sistema.
Cria um link para o dispositivo usando o comando installf.
Finaliza a instalação usando o comando installf -f.
Cria um script preremove.
O script preremove usa o comando rem_drv para descarregar o driver do sistema e, em seguida, remove o link /dev/buffer0 .
PKG=bufdev NAME=Buffer Device CATEGORY=system BASEDIR=/ ARCH=INTEL VERSION=Software Issue #19 CLASSES=none |
Para instalar um driver no momento da instalação, você deve incluir os arquivos de objeto e de configuração do driver no arquivo prototype.
Neste exemplo, o módulo executável do driver é nomeado buffer. O comando add_drv opera neste arquivo. O kernel usa o arquivo de configuração, buffer.conf, para ajudar a configurar o driver.
i pkginfo i request i postinstall i preremove f none $KERNDIR/buffer 444 root root f none $KERNDIR/buffer.conf 444 root root |
Ao observar o arquivo prototype deste exemplo, note o seguinte:
Visto que os objetos de pacote não precisam de nenhum tratamento especial, você pode colocá-los na classe none padrão. O parâmetro CLASSES está definido como none no arquivo pkginfo.
Os nomes de caminho de buffer e buffer.conf começam com a variável $KERNDIR. Esta variável está definida no script request e permite que o administrador decida onde os arquivos de driver devem ser instalados. O diretório padrão é /kernel/drv.
Há uma entrada para o script postinstall (o script que realizará a instalação do driver).
trap 'exit 3' 15 # determine where driver object should be placed; location # must be an absolute path name that is an existing directory KERNDIR=`ckpath -aoy -d /kernel/drv -p \ “Where do you want the driver object installed”` || exit $? # make parameters available to installation service, and # so to any other packaging scripts cat >$1 <<! CLASSES='$CLASSES' KERNDIR='$KERNDIR' ! exit 0 |
# KERNDIR parameter provided by `request' script err_code=1 # an error is considered fatal # Load the module into the system cd $KERNDIR add_drv -m '* 0666 root sys' buffer || exit $err_code # Create a /dev entry for the character node installf $PKGINST /dev/buffer0=/devices/eisa/buffer*:0 s installf -f $PKGINST |
err_code=1 # an error is considered fatal # Unload the driver rem_drv buffer || exit $err_code # remove /dev file removef $PKGINST /dev/buffer0 ; rm /dev/buffer0 removef -f $PKGINST |
Este estudo de caso descreve como instalar um driver usando a classe sed e scripts de procedimento. Também é diferente do estudo de caso anterior (consulte Instalando e removendo um driver com scripts de procedimento) porque este pacote está composto de objetos absolutos e relocáveis.
Este estudo de caso demonstra as seguintes técnicas:
Construção de um arquivo prototype com objetos absolutos e relocáveis.
Para obter informações sobre construção de um arquivo prototype, consulte Criando um arquivo prototype.
Uso de um script postinstall
Para obter mais informações sobre este script, consulte Escrevendo scripts de procedimento.
Uso de um script preremove
Para obter mais informações sobre este script, consulte Escrevendo scripts de procedimento.
Uso de um arquivo copyright
Para obter mais informações sobre este arquivo, consulte Escrevendo uma mensagem de copyright.
Criar um arquivo prototype contendo objetos de pacote absolutos e relocáveis.
Este tema é tratado detalhadamente em O arquivo prototype.
Adicionar o script de classe sed ao arquivo prototype.
O nome de um script deve ser o nome do arquivo que será editado. Neste caso, o arquivo a ser editado é /etc/devlink.tab e o script sed também é nomeado /etc/devlink.tab. Não há requisitos de modo, proprietário e grupo de um script sed (representado no prototype de amostra por pontos de interrogação). O tipo de arquivo do script sed deve ser e (indicando que é editável).
Definir o parâmetro CLASSES para incluir a classe sed.
Criar um script de ação de classe sed ( /etc/devlink.tab ).
Criar um script postinstall.
O script postinstall precisa executar o comando add_drv para adicionar o driver do dispositivo ao sistema.
Criar um script preremove.
O script preremove precisa executar o comando rem_drv para remover o driver do dispositivo do sistema, antes que o pacote seja removido.
Criar um arquivo copyright.
Um arquivo copyright contém o texto ASCII de uma mensagem de copyright. A mensagem que aparece no arquivo de amostra é exibida na tela durante a instalação do pacote.
PKG=SUNWsst NAME=Simple SCSI Target Driver VERSION=1 CATEGORY=system ARCH=sparc VENDOR=Sun Microsystems BASEDIR=/opt CLASSES=sed |
Este estudo de caso, por exemplo, usa o layout de hierarquia dos objetos de pacote mostrados na figura abaixo.
Os objetos de pacote são instalados nos mesmos locais que no diretório pkg acima. Os módulos do driver (sst e sst.conf) são instalados no /usr/kernel/drv e o arquivo incluído é instalado em /usr/include/sys/scsi/targets. Os arquivos sst, sst.conf e sst_def.h são objetos absolutos. O programa de teste, sstest.c, e seu diretório SUNWsst são relocáveis. O seu local de instalação é definido pelo parâmetro BASEDIR.
Os componentes restantes do pacote (todos os arquivos de controle) se encontram na parte superior do diretório do pacote na máquina de desenvolvimento, exceto o script de classe sed. Denomina-se devlink.tab depois do arquivo que ele modifica, e entra em etc, o diretório que contém o arquivo devlink.tab real.
Do diretório pkg, execute o comando pkgproto da seguinte forma:
find usr SUNWsst -print | pkgproto > prototype |
A saída do comando acima se assemelha à saída seguinte:
d none usr 0775 pms mts d none usr/include 0775 pms mts d none usr/include/sys 0775 pms mts d none usr/include/sys/scsi 0775 pms mts d none usr/include/sys/scsi/targets 0775 pms mts f none usr/include/sys/scsi/targets/sst_def.h 0444 pms mts d none usr/kernel 0775 pms mts d none usr/kernel/drv 0775 pms mts f none usr/kernel/drv/sst 0664 pms mts f none usr/kernel/drv/sst.conf 0444 pms mts d none SUNWsst 0775 pms mts f none SUNWsst/sstest.c 0664 pms mts |
Este arquivo prototype ainda não está completo. Para completar este arquivo, você precisa fazer as seguintes modificações:
Insira as entradas dos arquivos de controle (tipo de arquivo i), porque apresentam um formato diferente do formato dos outros objetos de pacote.
Remova as entradas dos diretórios que já existem no sistema de destino.
Altere a permissão de acesso e a propriedade de cada entrada.
Anteponha uma barra nos objetos de pacote absolutos.
Este é o arquivo prototype final:
i pkginfo i postinstall i preremove i copyright e sed /etc/devlink.tab ? ? ? f none /usr/include/sys/scsi/targets/sst_def.h 0644 bin bin f none /usr/kernel/drv/sst 0755 root sys f none /usr/kernel/drv/sst.conf 0644 root sys d none SUNWsst 0775 root sys f none SUNWsst/sstest.c 0664 root sys |
Os pontos de interrogação na entrada de cada script sed indicam que as permissões de acesso e a propriedade do arquivo existentes na máquina de instalação não devem ser alterados.
No exemplo de driver, um script de classe sed é usado para adicionar uma entrada ao arquivo /etc/devlink.tab no driver. Este arquivo é usado pelo comando devlinks para criar links simbólicos de /dev em /devices. Este é o script sed:
# sed class script to modify /etc/devlink.tab !install /name=sst;/d $i\ type=ddi_pseudo;name=sst;minor=character rsst\\A1 !remove /name=sst;/d |
O comando pkgrm não executa a remoção de parte do script. Você pode precisar adicionar uma linha ao script preremove para executar sed diretamente para remover a entrada do arquivo /etc/devlink.tab.
Neste exemplo, o script precisa apenas executar o comando add_drv.
# Postinstallation script for SUNWsst # This does not apply to a client. if [$PKG_INSTALL_ROOT = "/" -o -z $PKG_INSTALL_ROOT]; then SAVEBASE=$BASEDIR BASEDIR=””; export BASEDIR /usr/sbin/add_drv sst STATUS=$? BASEDIR=$SAVEBASE; export BASEDIR if [ $STATUS -eq 0 ] then exit 20 else exit 2 fi else echo "This cannot be installed onto a client." exit 2 fi |
O comando add_drv usa o parâmetro BASEDIR, de modo que o script tem que cancelar a definição de BASEDIR antes de executar o comando e restaurá-lo depois.
Uma das ações do comando add_drv é executar devlinks, que usa a entrada colocada em /etc/devlink.tab pelo script de classe sed para criar as entradas /dev no driver.
O código de saíca do script postinstall é importante. O código de saída 20 manda o comando pkgadd dizer ao usuário para reiniciar o sistema (necessário depois da instalação de um driver), e o código de saída 2 manda o comando pkgadd dizer ao usuário que a instalação falhou parcialmente.
No estudo de caso deste exemplo de driver, ele remove os links em /dev e executa o comando rem_drv no driver.
# Pre removal script for the sst driver echo “Removing /dev entries” /usr/bin/rm -f /dev/rsst* echo “Deinstalling driver from the kernel” SAVEBASE=$BASEDIR BASEDIR=””; export BASEDIR /usr/sbin/rem_drv sst BASEDIR=$SAVEBASE; export BASEDIR exit |
O script remove as entradas /dev. As entradas /devices são removidas pelo comando rem_drv.
É um arquivo ASCII simples que contém o texto de um aviso de copyright. O aviso é exibido no início da instalação do pacote exatamente como aparece no arquivo.
Copyright (c) 1999 Drivers-R-Us, Inc. 10 Device Drive, Thebus, IO 80586 All rights reserved. This product and related documentation is protected by copyright and distributed under licenses restricting its use, copying, distribution and decompilation. No part of this product or related documentation may be reproduced in any form by any means without prior written authorization of Drivers-R-Us and its licensors, if any. |