Лучшие практики Python Daemon Packaging - PullRequest
23 голосов
/ 26 февраля 2009

У меня есть инструмент, который я написал на python и обычно его следует запускать как демон. Каковы наилучшие практики для упаковки этого инструмента для распространения, в частности, как следует обрабатывать файлы настроек и исполняемый файл / скрипт демона?

В связи с этим существуют ли какие-либо общие инструменты для настройки демона для запуска при загрузке в зависимости от конкретной платформы (например, init сценарии для Linux, службы для Windows, launchd для ОС х)

Ответы [ 10 ]

14 голосов
/ 26 февраля 2009

Лучший инструмент, который я нашел для помощи со скриптами 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, который я всегда рекомендовал бы.

11 голосов
/ 26 февраля 2009

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

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

Windows - это совершенно другая игра, для которой потребуются расширения win32 Марка Хаммонда и, возможно, расширения WMI Тима Голдена.

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

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

8 голосов
/ 26 февраля 2009

В интернете есть множество фрагментов, предлагающих написать демон на чистом python (без скриптов bash)

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

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

В основном:

При запуске:

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

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

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

Я не знаю ни одного широко используемого пакета, делающего это, хотя.

5 голосов
/ 17 мая 2010

Проверьте модуль демона Бена Финни. Он начал писать PEP для Python 3.X:

http://www.python.org/dev/peps/pep-3143/

Но реализация уже доступна здесь:

http://pypi.python.org/pypi/python-daemon/

4 голосов
/ 26 декабря 2009

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

3 голосов
/ 26 февраля 2009

Не могу вспомнить, где я его скачал ... но это лучший демонизирующий скрипт, который я нашел. Он прекрасно работает (на 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 и т.д ...

0 голосов
/ 01 декабря 2016

поправьте меня, если не прав, но я верю, что вопрос в том, как ОГРАНИЧИТЬ демона. Установите ваше приложение для установки через pip, а затем сделайте entry_point a cli(daemon()). Затем создайте сценарий инициализации, который просто запускает $app_name &

0 голосов
/ 11 января 2012

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

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

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

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

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

Ответ Али Афшара - пример сценария оболочки второго подхода с использованием start-stop-daemon.

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

0 голосов
/ 26 февраля 2009

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

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

0 голосов
/ 26 февраля 2009

"вообще должен запускаться как демон?"

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

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

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

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

Мы используем /opt/ourapp для приложения (это Python, но мы не устанавливаем в 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.

...