1 сентября 2014 г.

Raspberry Pi + Raspbian = автозапуск программы при помощи upstart после синхронизации с NTP

В чем собственно проблема ?

Наверное у многих возникал вопрос, как настроить запуск программы при загрузке. Как известно, на raspberry pi отсутствуют RTC, то есть часы реального времени, поэтому при запуске можно увидеть дату примерного такого вида:

1 января 1970 00:01:00

что само собой не очень хорошо, если вам нужно точно знать время (неважно для чего). В Raspbian уже есть настроенный ntpd, который синхронизирует часы через интернет, все хорошо, НО, это происходит не моментально, и мы вполне можем получить абсолютно неверную дату и время (у меня считывались данные о температуре и влажности с метеостанции на базе Arduino), и получить данные образца 1970 года было совсем и совсем не круто). Поэтому и пришлось искать решение проблемы. Сегодня я расскажу как настроить автозапуск программы без лишних хлопот уже после синхронизации с серверами NTP

Что будем делать

В первую очередь установим Upstart (ВНИМАНИЕ! Лучше не делать этого на рабочей системе, во избежании так скажем, сделайте резервную копию образа системы !!!) Для установки upstart вводим в терминале:

sudo apt-get install upstart

На что система спросит, действительно ли мы хотим это сделать, вводим фразу целиком, которую просит apt. После установки перезагружаемся командой:

sudo reboot

Система должна загрузится без каких-либо проблем. Теперь надо сказать, что конфиги upstart хранятся в папке /etc/init и имеют формат .conf
Создадим в этой папке конфиг для нашей программы:

sudo nano /etc/init/your_serv.conf

Теперь набираем наш конфиг:

description "Program name"
author "Your name"

start on runlevel [2345]
stop on runlevel [!2345]

respawn
respawn limit 10 120

pre-start script
 until ntpq -np | grep -q '^\*';
 do
  echo "NTP not ready... wait"
  sleep 30
 done
end script

exec /usr/local/your_serv.py

post-start script
 echo "daemon started"
 date
end script

Теперь распишу конфиг подробно. description и author указывают, собственно, кто автор конфига и для чего оно надо, эти секции не обязательны, но лучше добавить описание, чтобы не забыть, для чего это вообще было нужно.

start on указывает, когда начинать запуск сервиса (в терминологии upstart), у нас указано, что запуск нужно производить на всех уровнях (про значения чисел и что такое уровни выполнения читаем тут)

stop on - на каких уровнях нужно останавливать сервис (восклицательный знак означает отрицание, то есть не на 2345, как в си)

Стоит наверное сказать, что в этих двух секциях не обязательно должны быть указаны уровни выполнения, upstart предоставляет возможность останавливать и запускать сервис после запуска, остановки, во время работы других сервисов, что позволяет довольно гибко выбирать что и когда у нас должно запускаться и останавливаться.

respawn и respawn limit указывают, что сервис должен перезапускаться при ошибке основной программы, respawn limit меняет значения по-умолчанию, в данном случае будет 10 попыток перезапуска с интервалами в 120 секунд.

pre-start указывает, что нам нужно делать перед запуском основной программы, собственно в этом месте мы и проверяем, синхронизировалась ли наша малинка с NTP.

Связка script ... end script используется когда нам нужно выполнить несколько команд, команды вводятся одна за другой как в обычном терминале, так же можно писать bash-скрипты (что в нашем случае и сделано). Нужно добавить, что после секций типа pre-start и им подобных должно обязательно следовать script или exec (используется если нужно запустить только одну команду).

exec указывает, что нам нужно запускать как основную программу, это так же может быть script ... end script. Но важно отметить, что в конфиге обязательно должен присутствовать exec или script, иначе все остальное просто бессмысленно. То есть данная секция строго обязательна.

post-script указывает, что делать после запуска основной программы. В нашем случае пишем, что запуск произошел и выводим дату как бонус.

Весь вывод, который делает стартовый конфиг или сама программа в консоль, хранится в файле /var/log/upstart/your_serv.log

Теперь запускаем наш сервис командой: sudo service your_serv start
Для остановки используем: sudo service your_serv stop 
Для перезапуска меняем stop на restart
Для проверки работает ли наша программа пишем: service your_serv status

Стоит сказать, что здесь мы использовали далеко не все возможности upstart и не все возможные настройки в конфиге. За подробностями идем на сайт upstart или просто вводим в терминале man 5 init и знакомимся с документацией в полном объеме (upstart должен быть предварительно установлен)

В конце объясню, как происходит проверка, что синхронизация с NTP успешна. Для этого используем ntpq, опции -np указывают что выводим сервера, с которыми происходит синхронизация, в качестве адресов выводи ip
Выглядит это примерно так:
edgar@edgar-desktop:~$ ntpq -pn
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+91.122.42.73    193.79.237.14    2 u    1   64   77   12.440   56.259  66.320
*79.165.63.245   .GPS.            1 u   63   64   37    2.492   23.173  62.735
+31.131.249.26   89.175.22.41     2 u   62   64   37   11.419   21.781  62.520
+85.159.224.52   89.109.251.21    2 u   63   64   37   32.024   23.979  61.772
 91.189.94.4     131.188.3.220    2 u   60   64   37   56.996   18.162  71.548

Собственно в скрипте вывод передается утилите grep, которая по шаблону ищет в начале каждой строки "*", которая указывает на тот сервер, с которым произошла синхронизация. А grep возвращает истину, если такая строка найдена. Подробнее про шаблоны и grep читаем здесь

Вот собственно и все, если возникнут проблемы или вопросы, пишем в комментариях или мне в личку в контакте сюда

Комментариев нет:

Отправить комментарий