2009-02-26 2 views
23

У меня есть инструмент, который я написал на питоне и вообще должен запускаться как демон. Каковы наилучшие методы упаковки этого инструмента для распространения, в частности, как обрабатывать файлы настроек и исполняемый файл/сценарий демона?Python Daemon Packaging Best Practices

Relatedly есть какие-то общие инструменты для настройки демона для запуска при загрузке системы по мере необходимости для данной платформы (т.е. INIT сценарии на Linux, услуги на окнах, на запуск программ OS X)?

+1

См. Также этот вопрос: http://stackoverflow.com/questions/473620/how-do-you-create-a-daemon-in-python – Rabarberski

ответ

11

Чтобы ответить на одну часть вашего вопроса, нет никаких инструментов, я знаю, что будет делать демон установки переносимых даже через системы Linux не говоря уже о Windows, или Mac OS X.

распределения

Большинство Linux, кажется, использует start-stop-daemon в init, но вы по-прежнему будете иметь небольшую разницу в макете файловой системы и больших различиях в упаковке. Использование autotools/configure или distutils/easy_install, если ваш проект является всем Python, значительно облегчит сбор пакетов для разных дистрибутивов Linux/BSD.

Windows - это совершенно другая игра и потребует расширения Mark Hammond's win32 и, возможно, Tim Golden's WMI.

Я не знаю Launchd, за исключением того, что «ни один из вышеперечисленных» не является релевантным.

Для советов по демонстрации скриптов Python я бы посмотрел на приложения Python, которые на самом деле делают это в реальном мире, например внутри Twisted.

14

Лучший инструмент, который я нашел для помощи с скриптами init.d, - «start-stop-daemon». Он запускает любое приложение, контролирует файлы run/pid, создает их, когда это необходимо, предоставляет способы остановить демона, устанавливать идентификаторы пользователя/группы процессов, а также может выполнять фоновый процесс.

Например, это скрипт, который можно запустить/остановить сервер WSGI:

#! /bin/bash 

case "$1" in 
    start) 
    echo "Starting server" 

    # Activate the virtual environment 
    . /home/ali/wer-gcms/g-env/bin/activate 

    # Run start-stop-daemon, the $DAEMON variable contains the path to the 
    # application to run 
    start-stop-daemon --start --pidfile $WSGI_PIDFILE \ 
     --user www-data --group www-data \ 
     --chuid www-data \ 
     --exec "$DAEMON" 
    ;; 
    stop) 
    echo "Stopping WSGI Application" 

    # Start-stop daemon can also stop the application by sending sig 15 
    # (configurable) to the process id contained in the run/pid file 
    start-stop-daemon --stop --pidfile $WSGI_PIDFILE --verbose 
    ;; 
    *) 
    # Refuse to do other stuff 
    echo "Usage: /etc/init.d/wsgi-application.sh {start|stop}" 
    exit 1 
    ;; 
esac 

exit 0 

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

-10

«Как правило, должен быть запущен как демон?»

Не имеет - на поверхности - имеет большой смысл. «Вообще» неразумно. Это либо демона, либо нет. Возможно, вы захотите обновить свой вопрос.

Для примеров демонов читайте демонов, таких как httpd Apache или любого сервера базы данных (они являются демонами) или SMTPD-почтового демона.

Или, может быть, прочитайте что-нибудь более простое, например, демон FTP, демон SSH, демон Telnet.

В мире Linux у вас будет каталог установки вашего приложения, какой-либо рабочий каталог, а также каталоги файлов конфигурации.

Мы используем /opt/ourapp для приложения (это Python, но не устанавливать в Питоне lib/site-packages)

/var/ourapp Мы используем для рабочих файлов и наших конфигурационных файлов.

Для конфигурационных файлов мы могли бы использовать /etc/ourapp - это было бы согласовано, но мы этого не делаем.

У нас пока нет сценариев init.d для запуска. Но это последний кусок, автоматический запуск. На данный момент у нас есть системные администраторы, которые запускают демонов.

Основано это частично на http://www.pathname.com/fhs/ и http://tldp.org/LDP/Linux-Filesystem-Hierarchy/html/Linux-Filesystem-Hierarchy.html.

+2

Вы довольно круто!? Демоны - это только демоны. Иногда бывает полезно запустить их как обычный процесс для Ctrl-c, проверить выход на stdout и т. Д. – fulmicoton

+0

@Paul: Согласен. Вы можете уточнить вопрос? –

0

В системах Linux системный диспетчер пакетов (Portage для Gentoo, Aptitude для Ubuntu/Debian, yum для Fedora и т. Д.) Обычно занимается установкой программы, включая размещение сценариев инициализации в нужных местах. Если вы хотите распространять свою программу для Linux, вам может потребоваться собрать ее в надлежащий формат для менеджеров пакетов различных дистрибутивов.

Этот совет, очевидно, не имеет отношения к системам, в которых нет менеджеров пакетов (Windows и Mac, я думаю).

+0

Существуют системы упаковки для многих других Unices! Например, pkgsrc для NetBSD. – bortzmeyer

+0

Интересно, я не знал, что –

8

Есть много фрагментов в Интернете предлагая написать демон в чистом питоне (без Баш скрипты)

http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ выглядит чистым ...

Если вы хотите, чтобы написать свой собственный,
принцип такой же, как и с функцией dahon bash.

В основном:

На старте:

  • вы раскошелиться на другой процесс
  • открыть файл журнал, чтобы перенаправить стандартный вывод и стандартный поток ошибок
  • Сохранить Идентификатор где-то.

На остановке:

  • Вы отправляете SIGTERM процесс с PID хранится в вашей PidFile.
  • С сигналом signal.signal (signal.SIGTERM, sigtermhandler) вы можете привязать процедуру остановки к сигналу SIGTERM.

Я не знаю, широко распространенный пакет делает это.

+1

+1 Для демона Python. Я на самом деле использую подобный рецепт для этого, за исключением того, что запускаю его с помощью start-stop-daemon из сценария Bash. Может быть, один шаг слишком много, но это дает мне теплое нечеткое чувство вести себя как все остальные демоны! –

3

Я не могу вспомнить, где я его загрузил ... но это лучший демон-сценарий, который я нашел. Он прекрасно работает (на Mac и Linux.) (Сохранить его как daemonize.py)

import sys, os 
def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): 
    # Perform first fork. 
    try: 
     pid = os.fork() 
     if pid > 0: 
      sys.exit(0) # Exit first parent. 
    except OSError, e: 
     sys.stderr.write("fork #1 failed: (%d) %sn" % (e.errno, e.strerror)) 
     sys.exit(1) 
    # Decouple from parent environment. 
    os.chdir("/") 
    os.umask(0) 
    os.setsid() 
    # Perform second fork. 
    try: 
     pid = os.fork() 
     if pid > 0: 
      sys.exit(0) # Exit second parent. 
    except OSError, e: 
     sys.stderr.write("fork #2 failed: (%d) %sn" % (e.errno, e.strerror)) 
     sys.exit(1) 
    # The process is now daemonized, redirect standard file descriptors. 
    for f in sys.stdout, sys.stderr: f.flush() 
    si = file(stdin, 'r') 
    so = file(stdout, 'a+') 
    se = file(stderr, 'a+', 0) 
    os.dup2(si.fileno(), sys.stdin.fileno()) 
    os.dup2(so.fileno(), sys.stdout.fileno()) 
    os.dup2(se.fileno(), sys.stderr.fileno()) 

В вашем сценарии, вы бы просто:

from daemonize import daemonize 
daemonize() 

И вы также можете указать места для перенаправления STDIO , err и т. д.

+4

Похоже на раннее построение этого: http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ –

3

Не серебряная пуля за то, о чем вы просите, но проверьте supervisord.Он обрабатывает все забавные бит управляющих процессов. Я использую его в большой производственной среде. Кроме того, он написан на Python!

0

Это blog entry ясно дал понять мне, что есть на самом деле два обычных способа заставить вашу программу Python работать как деамон (я так не понял это из существующих ответов):

Существует два подхода к написанию приложений-демонов, таких как серверы в Python.

  • Первый заключается в ручки все задачи sarting и остановки демонов в самом коде Python. Самый простой способ сделать это - с пакетом python-daemon, который может в конечном итоге сделать свой путь в дистрибутив Python.

Poeljapon's answer является примером такого подхода 1-го, хотя он не использует python-daemon пакет, но ссылки на обычай, но очень чистый питон скрипт.

  • Другой подход заключается в использовать инструменты , поставляемые операционной системой. В случае Debain это означает, что записывает сценарий инициализации, который использует программу start-stop-daemon .

Ali Afshar's answer является примером сценария оболочки 2-го подхода, используя start-stop-daemon.

Запись в блоге, которую я цитировал, имеет пример сценария оболочки и некоторые дополнительные сведения о таких вещах, как запуск вашего демона при запуске системы и автоматическое перезапуск вашего демона, когда он по какой-либо причине прекращается.

0

исправьте меня, если он ошибается, но я верю, что вопрос заключается в том, как DEPLOY-демона. Установите приложение для установки через pip, а затем введите entry_point a cli(daemon()). Затем создайте сценарий инициализации, который просто запускается $app_name &