Criando arquivos de configuração em /etc em pacotes Debian
Atualmente estou trabalhando em uma versão atualizada do picockpit-cliente, que deve adicionar arquivos de configuração adicionais em /etc/picockpit-cliente para os módulos individuais (PiDoctor & PiControl).
picockpit-cliente é um pacote Raspbian para picockpit.com, ligando a plataforma Web com o seu Raspberry Pi individual.
Como o Raspbian é baseado no Debian, as seguintes informações se aplicam ao empacotamento geral para o Debian e derivados (por exemplo, Ubuntu).
dh-virtualenv
Eu recomendo vivamente o meu outro artigo sobre empacotamento Debian como introdução e material adicional, caso você esteja interessado em empacotar aplicações Python.
Neste artigo irei discutir conceitos gerais relacionados com embalagem, e especificamente instalar ficheiros em /etc/
Uma nota à frente: O "ponto de entrada" para construir um pacote é o makefile debian/regras.
E você pode construir pacotes usando o seguinte comando:
dpkg-buildpackage -uc -us -b
Este comando é executado a partir do diretório top do seu pacote, não do diretório debian/.
Visão Geral Básica
Você pode ver uma estrutura de pastas necessária para um pacote Debian (contida na pasta picockpit-client-package).
Mais importante, contém uma pasta debianque contém vários arquivos de configuração usados para construir o pacote.
Este layout de arquivo é usado para construir o pacote usando debhelperque a maioria dos pacotes usa porque automatiza muitas tarefas.
changelog
Este arquivo contém informações do changelog (para o pacote debian). Ele é usado para definir a versão do pacote.
Exemplo de conteúdo:
Note que a recuo por espaços é necessário (dois espaços antes do símbolo *, um espaço antes do símbolo -)
No meu exemplo a versão mais recente do pacote (entrada no topo) é 0.18.5
compatriota
Este arquivo contém um número seguido por uma nova linha:
Esta é a versão de debhelper a sua aplicação é compatível com. (A partir da versão 12 isso também pode ser especificado no debian/control, mas ainda será suportado no debian/compat para compatibilidade com versões anteriores - veja isto manpage)
controle
Este arquivo é usado para fornecer dependências, nome do pacote e outros meta dados relevantes do pacote.
direitos autorais
Este arquivo fornece informações de direitos autorais para o seu pacote.
.install
No meu caso, o ficheiro chama-se picockpit-client.install, uma vez que o meu pacote é o pacote picockpit-client.
Este arquivo é avaliado por dh_instalar (que é parte do debhelper). Ele copia um arquivo ou vários arquivos para um diretório no pacote (para ser instalado mais tarde nesta localização absoluta do sistema).
Neste caso, eu quero o arquivo etc/dinosaur/dinosaur.cfg a ser instalado em /etc/dinosaur, como /etc/dinosaur/dinosaur.cfg
Um problema que encontrei ao pesquisar este tópico foi compreender, onde colocar etc/dinosaur/dinosaur.cfg, em relação ao picockpit-client.install.
É importante saber que em que locais de busca dh_install procura por estes arquivos.
Aqui está a resposta:
Por padrão, parece em "." e "debian/tmp".
"..." é o directório em que a pasta debian está contida.
Portanto, observe a estrutura da pasta:
Então, como você vê, "etc" está no mesmo nível de pasta que "debian". Por favor note que eu poderia ter nomeado isto arbitrariamente, já que eu especifique a localização no picockpit-client.install:
etc/dinosaur/dinosaur.cfg etc/dinosaur
Eu poderia modificar isso para ser simplesmente dinossauro.cfg, então dinossauro.cfg tem que estar no mesmo diretório pai que a pasta debian.
Por favor veja mais abaixo para mais informações sobre o papel especial dos ficheiros que vão para /etc, e uma importante dh_install debugging tip.
.links
Isto irá configurar links simbólicos, por exemplo, para adicionar a sua aplicação ao caminho do sistema no qual os binários estão sendo procurados:
.postinst
Um script que é executado após a instalação. set -e é importante neste script, ele também deve retornar 0 para indicar o sucesso (para que a instalação do pacote possa ser finalizada).
Eu tenho o padrão de um modelo:
.service
Esta é uma entrada de serviço do sistema a ser adicionada para a sua aplicação. Eu tenho, por exemplo:
.triggers
Não sei bem para que serve isto; parece-me (e funciona):
regras
regras é um makefile usado para construir o pacote. Isto irá variar, dependendo do tipo de pacote que você construir. Eu estou reproduzindo meu arquivo de regras aqui para sua conveniência.
Como você pode ver, ele usa dh_virtualenvO Python é uma solução para criar ambientes virtuais para código Python (permitindo que pacotes incompatíveis coexistam no mesmo sistema, e que você seja capaz de controlar o ambiente para o qual você implanta).
Se você está interessado no dh_virtualenv, leia o meu artigo sobre como empacotar pacotes Python para Raspbian com dh_virtualenv.
#!/usr/bin/make -f
#
# Construa o pacote Debian usando https://github.com/spotify/dh-virtualenv
#
# Os alvos abaixo criam uma cópia limpa do workdir através de
# usando "sdist", caso contrário "pip" fica sem fio ao instalar a partir de
# sourcedir ".", porque isso inclui a fase de construção da debian,
# e ocorre uma explosão recorrente quando são seguidas as ligações simbólicas.
#
# Também assegura que o seu MANIFESTO está completo e cobre pelo menos
# todos os arquivos necessários para uma compilação do release.# Aumentar o registro de rastreamento, ver debhelper(7) (descomentar para ativar)
#DH_VERBOSE=1exportar DH_VIRTUALENV_INSTALL_ROOT=/usr/share
SNAKE=/usr/bin/python3
EXTRA_REQUIREMENTS=-pré-instalar "setuptools>=17.1,=7" -preinstalar "wheel" -preinstalar "no-manylinux1
DH_VENV_ARGS=-com python-virtualenv -setuptools -python $(SNAKE) $(EXTRA_REQUIREMENTS) #-v
PACKAGE=$(shell dh_listpackages)
VERSION=$(shell $(SNAKE) setup.py -version)
SDIST_DIR=debian/$(PACKAGE)-$(VERSION)limpo:
teste ! -d dist || rm -rf dist
teste ! -d $(SDIST_DIR) || rm -rf $(SDIST_DIR)
dh $@ $(DH_VENV_ARGS)construção-arquitetura:
$(SNAKE) setup.py sdist -formatos de alcatrão
mkdir -p $(SDIST_DIR)
tar -x -C $(SDIST_DIR) -strip-components=1 -exclude '*.egg-info' -f dist/*.tar
#dh $@ $(DH_VENV_ARGS) -sourcedir $(SDIST_DIR) -sourcedir .
dh $@ $(DH_VENV_ARGS) -sourcedir .%:
#dh $@ $(DH_VENV_ARGS) -sourcedir $(SDIST_DIR) -sourcedir .
dh $@ $(DH_VENV_ARGS) -sourcedir .
Por favor, note que o WordPress tende a bagunçar a sintaxe do código, então use-o apenas como um guia aproximado, não para copiar e colar!
Mais informações sobre /etc, e dh_install
Sidenote importante / correção de bugs
Eu passei muito tempo a depurar o seguinte problema:
dh_install: Não é possível encontrar (qualquer correspondência para) "etc/dinosaur/dinosaur.cfg" (experimentado em debian/picockpit-client-0.18.5, debian/tmp)
dh_install: picockpit-cliente ficheiros em falta: etc/dinosaur/dinosaur.cfg
dh_install: ficheiros em falta, abortar
Este problema está relacionado com uma entrada "errada" em debian/regras
como você pode ver aqui, nesta (para iniciantes) sintaxe um tanto esmagadora e críptica, um parâmetro chamado -sourcedir está sendo definido para o comando dh nas entradas build-arch e %:
No dh_instalar documentação, podemos ler que este parâmetro configura em qual diretório de origem os arquivos devem ser pesquisados para a instalação.
Uma vez que isto tinha sido definido no meu debian/regras dh_install estava procurando no debian/picockpit-client-0.18.5 e debian/tmp - mas não no diretório de nível superior.
O conserto é simples:
dh $@ $(DH_VENV_ARGS) -sourcedir .
Eu simplesmente passo "." como nome do diretório para -sourcedir
Por favor, note que a passagem de duas entradas de origem não irá funcionar como esperado:
neste caso, a primeira entrada vai ser sobregravada:
Então apenas "." vai ser verificado, e o diretório passado em $(SDIST_DIR) não.
etc. é especial
dh_install trata os arquivos a serem instalados em etc como o chamado Conffiles.
Isto é automaticamente determinado, você não precisa adicionar nenhuma configuração adicional para isto (basta adicionar o arquivo de configuração como uma linha no seu .install file).
Para dizer novamente: se você usa o debhelper para sua embalagem, você faz não necessidade de criar o Conffiles no diretório debian manualmente. debhelper fará isso por você.
O dpkg gerencia esses arquivos de configuração, e garante que a configuração do usuário seja salva entre atualizações de pacotes, e na simples remoção de pacotes.
Leia esta maravilhosa visão geral sobre o que os conffiles significam para os usuários por Raphael Hertzog.
Digamos que eu instalei meu pacote (com um /etc/dinosaur/dinosaur.cfg fictício).
Eu então adicionei uma entrada adicional "New Dino adventures" em /etc/dinosaur/dinosaur.cfg
Se eu simplesmente remover o pacote:
apt-get remove picockpit-cliente
Então o pacote será removido, mas o arquivo de configuração ficará para trás:
Para nos livrarmos também do ficheiro de configuração modificado, precisamos de purgar o pacote:
apt-get purge picockpit-cliente
Ele irá informá-lo sobre o que está a fazer: "Purgar ficheiros de configuração para picockpit-cliente (0.18.5) ..."
Nota: você não precisa modificar o arquivo de configuração para que ele fique para trás se você remover o pacote. Um arquivo não modificado também ficará para trás.
OK, agora digamos que você modificou o arquivo e está prestes a atualizar ou reinstalar o pacote:
Neste caso, sua versão modificada permanecerá (ou você será avisado):
As versões dos arquivos de configuração, e em qual versão suas modificações são baseadas, são provenientes de somas MD5.
Você pode inspecionar estes md5sums por:
dpkg -status picockpit-cliente
Como você pode ver, na seção Conffiles o arquivo /etc/dinosaur/dinosaur.cfg é mostrado com sua soma MD5 original.
O dpkg pode comparar a soma MD5 entre as atualizações do pacote, e ver se a versão do mantenedor muda.
Caso você não modifique o arquivo de configuração original (como usuário do sistema), a nova versão do mantenedor será instalada.
Se ambos tiverem modificado seus arquivos, então você será solicitado a fazer uma escolha.
Referências
- debhelper manpage (incluindo uma lista de comandos debhelper dh_xx)
- Raphael Hertzog's informações sobre os conffiles
- https://www.debian.org/doc/manuals/maint-guide/dother.en.html
- https://www.debian.org/doc/manuals/packaging-tutorial/packaging-tutorial.en.pdf
- https://vincent.bernat.ch/en/blog/2019-pragmatic-debian-packaging
- https://manpages.debian.org/buster/debhelper/dh_installdeb.1.en.html
Para dh_virtualenv:
- https://pi3g.com/2019/04/19/packaging-python-projects-for-debian-raspbian-with-dh-virtualenv/
- https://dh-virtualenv.readthedocs.io/en/1.1/
- https://github.com/1and1/debianized-jupyterhub (um exemplo que também contém um arquivo .install)