Como posso ter certeza de que um trabalho do Upstart começa antes de outros trabalhos do Upstart?

34

Esta é uma questão geral do Upstart, mas deixe-me usar um caso específico:

Centrify é um NIS para o gateway ActiveDirectory. Ele precisa ser carregado antes de qualquer serviço que dependerá do serviço de autenticação que ele fornece, por exemplo, autofs, cron, nis, et al.

Isso tem se mostrado bastante desafiador, mesmo quando se tenta mudar as dependências dos outros serviços (o que eu acho que não deveríamos fazer de qualquer maneira, eu não quero tocar nos outros trabalhos do Upstart se tudo é possível).

Sugestões?

    
por Mark Russell 13.01.2011 / 17:43

2 respostas

12

A resposta de James funciona para uma dependência de 1 para 1. Para um número 1 a muitos, ou seja, para garantir que o serviço A seja iniciado antes dos serviços B, C e D, é necessário adotar outra abordagem. Você pode ver os scripts atuais do portmap para referência, mas aqui está a abordagem geral: crie um script de espera.

Cenário: você quer que seu Serviço A seja sempre executado antes de service-b, service-c e service-d.

Solução: crie um script de espera para o Serviço A. Chame-o de "/etc/init/service-a-wait.conf"

# service-a-wait

start on (starting service-b 
    or starting service-c
    or starting service-d)
stop on (started service-a or stopped service-a)

# We know that we have more than one job that needs to wait for service-a and
# will make use of this service, so we need to instantiate.
instance $JOB

# Needed to make starting the job successful despite being killed
normal exit 2
task

script

    status service-a | grep -q "start/running" && exit 0
    start service-a || true

    # Waiting forever is ok.. upstart will kill this job when
    # the service-a we tried to start above either starts or stops
    while sleep 3600 ; do :; done

end script

O que isso significa em inglês simples é: quando o serviço b, c ou d sinaliza que eles querem iniciar, eles devem esperar para iniciar até que o serviço-a esteja em execução. O serviço de espera é projetado para ser executado até que o serviço-a seja iniciado. Assim que o serviço-a-espera termina, agora os serviços b, c e d estão livres para continuar e executar.

Isso garantirá que o serviço-a esteja ativo e em execução antes que qualquer uma de suas dependências reversas tente iniciar.

Nota: a linha "instance $ JOB" é importante neste cenário "start on ... or .. or ..". Caso contrário, você só bloqueará realmente, seja qual for B, C ou D, disparando primeiro.

(instanciação merece uma explicação melhor honestamente. por enquanto, apenas faça isso.)

    
por Mark Russell 19.03.2011 / 04:37
30

A solução é abordar o problema da outra direção: para satisfazer os critérios iniciais do Centrify, não é necessário tornar os serviços existentes depende do novo serviço Centrify, em vez de fazer o novo serviço Centrify dependem de serviços existentes.

Por exemplo, um arquivo de configuração do Upstart /etc/init/centrify.conf poderia dizer:

  

inicie (iniciando o cron ou iniciando o autofs ou iniciando nis)

Convertendo isso para o inglês, isso seria traduzido como:

  

inicie o serviço Centrify antes do cron, autofs ou nis     start (o que começar primeiro).

A ordem em que o cron, autofs ou nis são iniciados é irrelevante: o Upstart garante que o Centrify será iniciado antes do primeiro serviço, garantindo assim que o Centrify está sendo executado antes que qualquer um desses serviços seja iniciado.

Note também que o Upstart irá bloquear o início do primeiro serviço que deseja iniciar até que o Centrify tenha iniciado a execução.

Muito elegante e simples quando você se acostuma a pensar dessa maneira.

    
por James Hunt 18.01.2011 / 12:40