Подтвердить что ты не робот

Рекомендации по лучшей упаковке Python Daemon

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

Кроме того, существуют ли какие-либо общие инструменты для настройки демона для запуска при загрузке, подходящего для данной платформы (например, сценарии инициализации на Linux, услуги в Windows, запуск на os x)?

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

Например, это script, который может запустить/остановить сервер 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

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

Ответ 3

В Интернете есть много фрагментов, предлагающих писать демона в чистом сценарии python (no bash)

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

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

В принципе:

В начале:

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

Остановка:

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

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

Ответ 5

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

Ответ 6

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

В script вы просто:

from daemonize import daemonize
daemonize()

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

Ответ 7

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

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

Ответ 8

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

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

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

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

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

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

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

Ответ 9

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

Ответ 10

"обычно должен выполняться как демон?"

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

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

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

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

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

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

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

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

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