Eu criei um script init.d chamado rmCluster que deve executar um script python simples no desligamento que usa o boto para desligar um determinado cluster de servidores, com 755 perms, localizado em /etc/init.d/rmCluster
escrito como:
#!/bin/sh
#
# chkconfig: 0 1 1
# description: My service
#
# Author: Me
#
#
### BEGIN INIT INFO
# Provides: rmCluster
# Required-Start:
# Required-Stop:
# Default-Start: 0
# Default-Stop: 0
# Short-Description: My service
# Description: My service
### END INIT INFO
case $1 in
start)
python /usr/local/sbin/instanceStopper.py &
touch /tmp/theScriptWorks
;;
esac
exit 0
Também criei um link simbólico em /etc/rc0.d/S00rmCluster
, que aponta para o acima. Observe que estou tocando um arquivo em / tmp que está ocorrendo com sucesso.
O script python também tem 755 permissões e está escrito como:
#!/usr/bin/env python
import boto.ec2
import subprocess
conn=boto.ec2.connect_to_region("us-west-2")
reservations = conn.get_all_instances()
cluster = []
inst_id = subprocess.Popen(["wget", "-q", "-O", "-", "http://169.254.169.254/latest/meta-data/instance-id"], stdout=subprocess.PIPE).communicate()[0]
for res in reservations:
for inst in res.instances:
if inst_id in inst.tags["Name"] and "cloudformation" not in inst.tags:
cluster.append( "%s" %(inst.id) )
conn.terminate_instances(cluster)
Note que o script python funciona perfeitamente quando chamado diretamente e também funciona bem quando executar o script init.d diretamente. Eu também tentei remover o shebang no script python e especificando o caminho para o python dentro do init.d call e ele ainda não funciona.
Minha inicial é que talvez as bibliotecas python não estejam mais disponíveis durante esse tempo de execução, então o script falha, mas não tenho certeza de como verificar isso. Além disso, eu contemplei que talvez ele precise ser colocado em algum outro lugar nos diretórios rc.x. Atualmente eu tenho definido em S00 e é o único S00. Killall eu mudei para S01 e parei de me mudar para S02; estes são os únicos três scripts "S" dentro do rc.0 /
Eu gostei da ajuda
Solução
A solução foi uma combinação de entrada da resposta de @Jayan e @Kjetil Joergensen.
A versão final de trabalho do script init.d é a seguinte:
#!/bin/bash
#
# chkconfig: 2345 99 1
# description: My service
#
# Author: me
#
#
### BEGIN INIT INFO
# Provides: rmCluster
# Required-Start:
# Required-Stop:
# Default-Start: 0
# Default-Stop: 0
# Short-Description: My service
# Description: My service
### END INIT INFO
case "$1" in
start)
touch /var/lock/subsys/rmCluster
;;
stop)
/usr/bin/python /usr/local/sbin/instanceStopper.py
;;
esac
exit 0
As principais mudanças foram:
- Mover a parte "start" em uma parte "stop"
- Tocando no arquivo de bloqueio na parte "início"
- Modificando o parâmetro 'chkconfig:' para que ele 'inicie' com os serviços normais e seja morto com eles também, evitando assim que o script tente executar o desligamento após 'rede', como notado por @Kjetil Joergensen
Nota: o script python não foi alterado.
Duas ressalvas, uma é que é necessário executar service start rmCluster
para que seja encerrado durante o nível de execução 0 e 6. Para mim, isso foi aceitável, pois está sendo configurado durante o provisionamento de formação de nuvens, portanto é trivial adicionar esse passo nos dados do usuário do EC2. A segunda é que o script é executado durante as reinicializações, o que pode não ser ideal para cada caso de uso. Vou ter que fazer uma investigação mais aprofundada para ver como fazer com que apenas o nível de execução 0 realmente execute 'stop' neste script.
Obrigado a ambos pela ajuda.