Назад | Перейти на главную страницу

Часть скрипта Python не выполняется в init.d / RedHat 6.5, почему?

Я создал сценарий init.d под названием rmCluster который должен выполнять простой скрипт python при выключении, который использует boto для выключения определенного кластера серверов с 755 perms, расположенных в /etc/init.d/rmCluster написано как:

#!/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

Я также создал символическую ссылку на /etc/rc0.d/S00rmCluster что указывает на вышесказанное. Обратите внимание, что я касаюсь файла в / tmp, который успешно выполняется.

Скрипт python также имеет 755 разрешений и записывается как:

#!/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)

Обратите внимание, что скрипт python отлично работает при прямом вызове, а также при прямом запуске скрипта init.d. Я также попытался удалить shebang в скрипте python и указать путь к python в вызове init.d, но он все еще не работает.

Мое первое, однако, заключается в том, что, возможно, библиотеки python больше не доступны во время этого выполнения, поэтому сценарий не работает, но я не уверен, как это проверить. Кроме того, я подумал, что, возможно, его нужно разместить где-то еще в каталогах rc.x. В настоящее время я установил на S00, и это единственный S00. Killall Я перешел на S01 и остановился, я перешел на S02; это единственные три скрипта "S" в rc.0 /

Я очень благодарен за помощь

Решение

Решением стало сочетание ответов @Jayan и @Kjetil Joergensen.

Финальная рабочая версия скрипта init.d выглядит следующим образом:

#!/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

Основные изменения:

  1. Перемещение части "начало)" в часть "стоп)"
  2. Касание файла блокировки в части "начало)"
  3. Изменение параметра 'chkconfig:' таким образом, чтобы он 'запускался' с обычными службами и также был убит вместе с ними, тем самым предотвращая попытку сценария выполнить завершение после 'сетевого' завершения, как заметил @Kjetil Joergensen

Примечание: Скрипт python не изменился.

Два предостережения, первое - для запуска требуется service start rmCluster для того, чтобы он отключился во время уровней запуска 0 и 6. Для меня это было приемлемо, поскольку он настраивается во время подготовки облачной информации, поэтому добавить этот шаг в данные пользователя EC2 тривиально. Во-вторых, сценарий также выполняется во время перезагрузки, что не всегда идеально подходит для каждого случая использования. Мне нужно будет провести дальнейшее исследование, чтобы увидеть, как сделать так, чтобы только уровень запуска 0 действительно выполнял «стоп» для этого скрипта.

Спасибо вам обоим за помощь.

(Почти) Все, что вам нужно знать, находится в /etc/rc.d/rc, это сценарий оболочки, который используется для изменения уровней выполнения, он довольно читабелен, так как должно быть довольно легко понять, что он делает.

Краткое описание того, что он делает:

  • Сначала он просматривает каждый сценарий /etc/rc<runlevel>.d/K <num> <subsystem>, проверяет, запущен ли он, ища / var / lock / subsys /, и запускает остановку, если он
  • Затем он просматривает каждый сценарий /etc/rc<runlevel>.d/S <num> <subsystem>, проверяет, остановлен ли он, проверяя / var / lock / subsys / <subsystem>, и запускает запуск на нем.

(Вероятно, есть какая-то удобная функция для работы с / var / lock / subsys)

Если все, что было до этого, верно, то, вероятно, вы захотите:

  • Убедитесь, что присутствует / var / lock / subsys / <yourscriptname>
  • Уровень выполнения 0 кажется подходящим (если вы также не хотите включить перезагрузку, которая равна 6), и вы захотите запустить его как /etc/rc0.d/K<num <90> <yourscriptname>, сеть отключается на 90 , поэтому отключите реализацию, чтобы не запускать, а останавливать. Вы также можете «запустить» свой скрипт как часть соответствующих уровней выполнения (3,5, 1 - одиночный пользователь без сети, а 2,4 - неиспользуемый), просто оставив соответствующие вещи в / var / lock / subsys.
  • Вы определенно хотите избавиться от амперсанда, так как ваш initscript вернется до того, как он будет выполнен, в зависимости от того, как быстро он проглотит остальные скрипты, он достигнет 90 и отключит сеть, в какой-то момент позже он получит убить всех и в конце концов остановиться. Чтобы избежать зависания завершения работы на неопределенный срок, вы захотите выполнить соответствующую обработку ошибок / тайм-аутов в своем скрипте, а не просто запускать его и оставлять остальное на волю случая.

Почему бы вам не попробовать изменить сценарий инициализации, чтобы начать с

chkconfig: 2345 99 1

И переместите свой код из case "Start" в "stop" и оставьте пустой регистр "start". Затем выполните chkconfig --add после помещения вашего скрипта в /etc/init.d

Примечание. Возможно, вам придется удалить любые уже созданные программные ссылки.

Также убедитесь, что у вас загружен правильный "PATH" при выполнении вашего сценария инициализации. Поскольку ваша программа Python уже является исполняемым файлом, возможно, вы можете просто назвать ее как

/ путь / к / программе &

вместо того

python / путь / к / программе и

Также в разделе "start" файла инициализации добавьте следующую строку:

коснитесь / var / lock / subsys / program

Что в основном создает файл блокировки и когда машина перезагружается | остановки, система проверит состояние каждой службы перед инициированием остановки. Если система обнаруживает, что служба не запущена (если файл блокировки отсутствует), система может не запустить процедуру «остановки».