git, nagios e hooks, repositório git corrompido


14

fundo

Estamos usando nagios para monitorar nossa infraestrutura. No momento, não temos as configurações do nagios sob controle de versão e há dois de nós que gerenciam a configuração do nagios. Como tal, estou trabalhando para obter nossa configuração do nagios em um repositório central do git, usando alguns ganchos para verificar a sintaxe e, se as configurações estiverem boas, torne-as "ativas". Estou usando o post desse cara como ponto de partida.

O fluxo de trabalho geral que estou tentando implementar é:

  1. Edite o repositório git local da configuração do nagios. Adicione arquivos editados, confirme localmente.
  2. git push origin master para o repo remoto.
  3. O push é interceptado pelo gancho de pré-recebimento, que pega os arquivos, os move para um diretório temporário no servidor e os executa pelo verificador de sintaxe nagios.
  4. Se o verificador de sintaxe for aprovado, aceite o envio e use o gancho pós-confirmação para git pullo novo código no diretório de configuração do nagios ativo e, em seguida, reinicie o nagios.
  5. Se o verificador de sintaxe falhar, rejeite o push, mostrando o erro de sintaxe do nagios ao usuário.

No entanto, estou tendo um comportamento estranho quando rejeito um push do git devido a erros de sintaxe na configuração do nagios. O que eu espero que aconteça é que, se eu rejeitar o gancho, a tentativa de envio deve deixar o repositório como estava, intocado. Mas esse não parece ser o caso. Abaixo estão os detalhes do que estou vendo:

Problema

Eu edito a configuração do nagios localmente, incluindo intencionalmente um erro de sintaxe, adiciono e confirmo localmente:

host:nagios erik$ vi nagios.cfg
host:nagios erik$ git add nagios.cfg
host:nagios erik$ git commit -m "syntax error"
[master da71aed] syntax error
 1 files changed, 1 insertions(+), 0 deletions(-)

Agora eu envio essas alterações para o repositório principal. Isso será rejeitado devido ao erro de sintaxe:

host:nagios erik$ git push origin master
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 12.74 KiB, done.
Total 3 (delta 1), reused 2 (delta 1)
remote: Previous HEAD position was 3ddc880... removed syntax error
remote: HEAD is now at da71aed... syntax error
remote: Nagios Config Check Exit Status: 254
remote: Your configs did not parse correctly, there was an error. Output follows.
remote:
remote: Nagios Core 3.2.3
remote: Copyright (c) 2009-2010 Nagios Core Development Team and Community Contributors
remote: Copyright (c) 1999-2009 Ethan Galstad
remote: Last Modified: 10-03-2010
remote: License: GPL
remote:
remote: Website: http://www.nagios.org
remote: Reading configuration data...
remote: Error in configuration file '/tmp/nagiosworkdir/nagios.cfg' - Line 23 (NULL value)
remote:    Error processing main config file!
remote:
remote:
remote:
remote: ***> One or more problems was encountered while processing the config files...
remote:
remote:      Check your configuration file(s) to ensure that they contain valid
remote:      directives and data defintions.  If you are upgrading from a previous
remote:      version of Nagios, you should be aware that some variables/definitions
remote:      may have been removed or modified in this version.  Make sure to read
remote:      the HTML documentation regarding the config files, as well as the
remote:      'Whats New' section to find out what has changed.
remote:
To git@remote-server.example.com:nagios
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@remote-server.example.com:nagios'

Isso não deveria ter afetado o repositório remoto, mas sim. Se eu mudar para outro diretório temporário local e tentar clonar o repositório, eu obtenho:

host:temp erik$ git clone git@remote-server.example.com:nagios
Cloning into nagios...
remote: Counting objects: 30, done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 30 (delta 12), reused 0 (delta 0)
Receiving objects: 100% (30/30), 29.81 KiB, done.
Resolving deltas: 100% (12/12), done.
error: Trying to write ref HEAD with nonexistant object da71aedfde2e0469288acd9e45bb8b57a6e5a7b3
fatal: Cannot update the ref 'HEAD'.

Agora volto ao diretório de trabalho original, corrijo o erro de sintaxe, adiciono, confirmo e pressiono:

host:nagios erik$ vi nagios.cfg
host:nagios erik$ git add nagios.cfg
host:nagios erik$ git commit -m "removing syntax error, push should succeed this time"
[master f147ded] removing syntax error, push should succeed this time
 1 files changed, 0 insertions(+), 2 deletions(-)
host:nagios erik$ git push origin master
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 487 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Previous HEAD position was 4c80d45... syntax error
remote: HEAD is now at f147ded... removing syntax error, push should succeed this time
remote: Nagios Config Check Exit Status: 0
remote: Your configs look good and parsed correctly.
To git@remote-server.example.com:nagios
   3ddc880..f147ded  master -> master

Neste ponto, o repositório está bom, e eu posso mudar para um diretório temporário e clonar o repositório novamente:

host:temp erik$ git clone git@remote-server.example.com:nagios
Cloning into nagios...
remote: Counting objects: 34, done.
remote: Compressing objects: 100% (33/33), done.
remote: Total 34 (delta 14), reused 0 (delta 0)
Receiving objects: 100% (34/34), 30.22 KiB, done.
Resolving deltas: 100% (14/14), done.

Aqui está o gancho de pré-recebimento que estou usando.

Estou usando o git v1.7.5.4 no cliente e v1.7.2.3 no servidor.

Então, para a pergunta : por que o repositório está sendo deixado em um estado inconsistente quando rejeito o envio? Há algo errado com meu gancho git ou talvez meu entendimento sobre git esteja faltando?


Qual versão do git você está usando?
21812 robbyt

@robbyt - 1.7.5.4no cliente, 1.7.2.3no servidor.
EEAA

Respostas:


7

Voce esta fazendo:

export GIT_WORK_TREE=/tmp/nagiosworkdir
/usr/bin/git checkout -f $NEW_SHA1

no seu gancho. Embora não está tocando o seu habitual trabalho-copiá-lo está atualizando referências no git-dir (especificamente o HEADde referência), como mostrado no seu erro:

...
remote: HEAD is now at da71aed... syntax error
...

Seu gancho está fazendo exit 1para rejeitar a atualização, mas não está (re) redefinindo a HEADreferência após falha.

Eu acho que você precisa atualizar o ramo de falha no seu gancho da seguinte forma:

...
if [ "$NAGIOS_CHECK_STATUS" -ne 0 ]
   then
   echo "Your configs did not parse correctly, there was an error. Output follows."
   cat $GIT_WORK_TREE/check.out
   /usr/bin/git reset --hard $OLD_SHA1    # <-- Add This
   exit 1
else
   ...

Isso parece ótimo, nickgrim. Vou tentar um pouco mais tarde hoje. Obrigado!
EEAA

0

O git checkoutcomando no seu gancho está criando / atualizando a referência HEAD no seu repositório.

Se o seu repositório for um repositório simples, ele poderá viver sem uma referência HEAD (novos clones terão como padrão verificar sua ramificação principal , se houver uma); basta excluir a referência HEAD antes de sair (talvez em um trappara que você não precise fazer isso antes de cada um exitindividualmente). Em qualquer lugar "precoce" do seu script:

trap 'git update-ref -m "removing HEAD after temporary checkout to alternate workdir" -d HEAD "$NEW_SHA1"' 0

Se o seu repositório não estiver vazio ou você quiser manter uma referência HEAD (para que os clones, por padrão, façam check-out em outra ramificação), será necessário salvar a referência HEAD e restaurá-la antes de sair.

Primeiro, no repositório do servidor, redefina a referência HEAD para apontar para o ramo que você deseja fazer check-out por padrão em novos clones:

git symbolic-ref -m 'setting default branch for new clones' HEAD refs/heads/master

Em seguida, no seu script de gancho (em qualquer lugar antes do checkout):

# Restore HEAD symref when exiting
saved_HEAD=$(git symbolic-ref HEAD)
trap 'git symbolic-ref -m "restoring HEAD after temporary checkout to alternate workdir" HEAD "$saved_HEAD"' 0

A propósito, os pre-receiveganchos devem certificar-se de que leem completamente o stdin e processam todas as linhas em que são alimentados. Sair antes de consumir toda a entrada pode às vezes acionar um SIGPIPE no git-receive-packprocesso; isso provavelmente não aparece no seu caso se você pressionar apenas um árbitro de cada vez (desde que você leia pelo menos uma linha), mas é algo a ter em mente. Provavelmente, é mais fácil fazer esse gancho como um updategancho, no qual você só precisa se preocupar com um árbitro de cada vez e pode rejeitar o empurrão de cada árbitro individualmente (talvez você só se preocupe em manter a ponta do mestre "limpa"; enquanto você verifica e informe sobre as dicas de outros ramos, mas nunca os rejeite para que possam ser usados ​​para colaboração em trabalhos incompletos).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.