Como garantir a execução de um serviço usando o Chef?

10

Estou em uma situação em que o Chef pode iniciar um serviço (postgres), mas pode ser interrompido posteriormente fora da banda. Quero que um Chef subseqüente seja executado para que o serviço seja executado. Eu tentei isso:

service "postgresql" do
    action :start
end

Mas não tem efeito, dizendo (up to date)presumivelmente porque o Chef sabe que foi iniciado e não é capaz de dizer que parou. (Possivelmente devido a como service ... statusse comporta para este serviço?) Se eu escrever isso:

# anti-pattern warning!
execute "force-start-postgresql" do
  command "service postgresql start || /etc/init.d/postgresql start"
  action :run
end

Eu recebo o comportamento desejado. Também action :restartfaz funcionar. No entanto, estes parecem antipadrões devido à portabilidade (e potencialmente pará-lo antes de iniciá-lo novamente no último caso).

Então, como posso dizer ao Chef para iniciar à força o serviço, mesmo que ele ache que já está em execução?

Isso está usando o Chef 11.6, hospedado pelo OpsCode, e a receita padrão do postgresql. (Observe que isso é semelhante, mas acho que não é o mesmo que Como forçar ações em recursos "atualizados" no Chef?. )

--- EDIT (esclarecimento após publicação no jtimberland) ---

O -l debugaqui mostra:

DEBUG: service[postgresql] supports status, running
DEBUG: service[postgresql] is running

Mesmo quando não está em execução. Então isso soa como um bug, e eu estou interessado nisso. No entanto, estou principalmente interessado em saber se há uma maneira de informar ao Chef "sempre invoque o comando service start, ignorando a verificação de status". Essa é a questão aqui.

(Não sou especialista, mas acho que a maneira mais portátil de garantir a execução de um serviço é iniciá-lo e isso quase sempre é idempotente. OTOH verificar se um serviço está em execução é menos consistente e não vejo por que devemos nos importar !)

Parcialmente nublado
fonte

Respostas:

11

Por padrão, o Chef verifica se o serviço está em execução e o inicia se o serviço não estiver em execução.

Como isso determina que o serviço está sendo executado depende.

Por padrão, o Chef tentará corresponder ao nome do serviço ( postgresqlaqui) na tabela de processos usando ps.

ps -ef | grep postgresql

Essencialmente. O nome do serviço será usado para a correspondência de padrões ao inspecionar a tabela de processos. Isso pode ou não ser o que você deseja / precisa, especialmente dependendo da plataforma e como ele nomeia o serviço "postgresql".

No entanto, você pode dizer ao Chef que o serviço suporta um comando "status", o que significa que o Chef geralmente fará algo como,

/etc/init.d/postgresql status

E use o código de retorno para determinar se está sendo executado ou não (diferente de zero não está sendo executado).

O Chef não faz isso por padrão, porque nem todos os scripts de serviço suportam um comando de status (frustrantemente), e o Chef não sabe por si próprio qual é a coisa certa a fazer. Ele tenta fazer a coisa padrão, mas às vezes ingênua. Assim, você pode dizer ao Chef que o recurso possui um comando de status e não é tão ingênuo.

service "postgresql" do
  supports :status => true
  action :start
end

Agora, se o serviço não for realmente chamado de "postgresql", mas sim "postgresql-92" ou similar, você pode fazer isso da seguinte maneira:

service "postgresql-92" do
  supports :status => true
  action :start
end

ou

service "postgresql" do
  service_name "postgresql-92"
  supports :status => true
  action :start
end

Você pode descobrir o que está acontecendo com mais detalhes executando chef com saída de depuração também:

chef-client -l debug
jtimberman
fonte
Isso é útil, mas não responde bem à pergunta. Eu quero dizer isso :start independentemente da :status. Também espero que faça um ps -ef | grep [p]ostgresqlou semelhante, caso contrário, ele geralmente corresponderá ao seu próprio comando grep e, portanto, sempre achará que o serviço está sendo executado. (Ou talvez esse é o problema subjacente?)
Parcialmente Nublado
Parece-me que existe um erro no Chef ou algo está errado no sistema. Qual plataforma / plataforma_versão você está executando? Como você instalou o postgresql? Pacote, fonte?
precisa
Para isso, o Chef executa ações idempotentes para gerenciar recursos definidos de forma declarativa. A maneira como você garante que um serviço esteja sendo executado com o Chef é enviar a ação inicial para o serviço. Se isso não estiver ocorrendo, é um erro no Chef, um erro na receita ou um erro no sistema.
precisa
Obrigado @jtimberman. Abri um bug para o status errado sendo retornado em tickets.opscode.com/browse/COOK-334 . No entanto, minha pergunta aqui é se existe uma maneira de forçar o chef a emitir o comando service-start, ignorando a verificação de status. service starté quase sempre idempotente, então isso deve ficar bem.
Parcialmente nublado
Desculpe, o bug é tickets.opscode.com/browse/COOK-3526 .
Parcialmente nublado