Ошибка импорта python локального модуля при запуске в качестве службы systemd/systemctl
У меня есть приложение python, которое я запускаю как системный сервис. Приложение работает нормально, когда я запускаю его вручную. Когда я запускаю его как службу, он не может найти локальный модуль, который был установлен с помощью pip install -e my_module
.
Основная часть приложения имеет следующий код:
print(sys.argv)
import pip
installed_packages = pip.get_installed_distributions()
installed_packages_list = sorted(["%s==%s" % (i.key, i.version) for i in installed_packages])
print(installed_packages_list)
print('doing tox')
import tox
print('doing my_mod')
import my_mod
print(my_mod.__file__)
from my_mod.auth.http_auth_provider import HTTPAuthProvider
Когда я запускаю его вручную, я получаю (обратите внимание, что my-mod включен во вторую строку в "установленных пакетах"):
['/usr/bin/pv_api']
['aiohttp==0.19.0', 'chardet==2.3.0', 'jsonschema==2.5.1', 'pip==7.0.0', 'pluggy==0.3.1', 'pv-api==0.0.0', 'py==1.4.31', 'pycrypto==2.6.1', 'pymongo==3.1.1', 'pyyaml==3.11', 'setuptools==19.6.2', 'six==1.10.0', 'tox==2.3.1', 'virtualenv==14.0.6', 'my-mod==0.1.0', 'webauthsession==1.1.1']
doing tox
doing my_mod
/root/my_module/my_mod/__init__.py
При запуске службы журналы выглядят так (обратите внимание, что my-mod НЕ включен во вторую строку в "установленных пакетах") ::
2016-02-26_00:39:01.90403 ['/usr/bin/pv_api']
2016-02-26_00:39:01.90406 ['aiohttp==0.19.0', 'chardet==2.3.0', 'jsonschema==2.5.1', 'pip==7.0.0', 'pluggy==0.3.1', 'pv-api==0.0.0', 'py==1.4.31', 'pycrypto==2.6.1', 'pymongo==3.1.1', 'pyyaml==3.11', 'setuptools==19.6.2', 'six==1.10.0', 'tox==2.3.1', 'virtualenv==14.0.6', 'webauthsession==1.1.1']
2016-02-26_00:39:01.90407 doing tox
2016-02-26_00:39:01.90407 doing my_mod
2016-02-26_00:39:01.90642 Traceback (most recent call last):
2016-02-26_00:39:01.90642 File "/usr/bin/pv_api", line 9, in <module>
2016-02-26_00:39:01.90642 load_entry_point('pv-api==0.0.0', 'console_scripts', 'pv_api')()
2016-02-26_00:39:01.90643 File "/usr/lib/python3.4/site-packages/pkg_resources/__init__.py", line 547, in load_entry_point
2016-02-26_00:39:01.90643 return get_distribution(dist).load_entry_point(group, name)
2016-02-26_00:39:01.90643 File "/usr/lib/python3.4/site-packages/pkg_resources/__init__.py", line 2719, in load_entry_point
2016-02-26_00:39:01.90643 return ep.load()
2016-02-26_00:39:01.90643 File "/usr/lib/python3.4/site-packages/pkg_resources/__init__.py", line 2379, in load
2016-02-26_00:39:01.90643 return self.resolve()
2016-02-26_00:39:01.90643 File "/usr/lib/python3.4/site-packages/pkg_resources/__init__.py", line 2385, in resolve
2016-02-26_00:39:01.90644 module = __import__(self.module_name, fromlist=['__name__'], level=0)
2016-02-26_00:39:01.90644 File "/usr/lib/python3.4/site-packages/pv/api/main.py", line 33, in <module>
2016-02-26_00:39:01.90644 import my_mod
2016-02-26_00:39:01.90644 ImportError: No module named 'my_mod'
Это также может быть полезной информацией:
[[email protected] etc]# ls -la /usr/lib/python3.4/site-packages/my-mod.egg-link
-rw-r--r-- 1 root root 37 Feb 26 00:20 /usr/lib/python3.4/site-packages/my-mod.egg-link
[[email protected] etc]# cat /usr/lib/python3.4/site-packages/my-mod.egg-link
/root/my_module
Редактировать:
Как видно из вывода "installed_packages", все остальные пакеты, установленные с помощью требования.txt, находятся правильно. Только эта библиотека, в которой у меня есть исходный код для локального, не найден, когда я запускаю службу. (Он обнаруживается при запуске из командной строки или при запуске import my_mod
из интерпретатора python3.
Ответы
Ответ 1
У меня была очень похожая проблема с преобразованием upstart heartbeat.conf
в systemd heartbeat.service
, за исключением модуля requests
. Решение заключалось в том, чтобы указать в новом.service, какой пользователь должен запускать его как:
[Unit]
Description=web server monitor
[Service]
WorkingDirectory=/home/user/
User=user
ExecStart=/home/user/heartbeat.py
Restart=always
[Install]
WantedBy=multi-user.target
Без User=user
я попал в журналctl:
systemd[1]: Started web server monitor.
heartbeat.py[26298]: Traceback (most recent call last):
heartbeat.py[26298]: File "/home/user/heartbeat.py", line 2, in <
heartbeat.py[26298]: import requests
heartbeat.py[26298]: ImportError: No module named requests
systemd[1]: heartbeat.service: Main process exited, code=exited, status=1/FAILURE
systemd[1]: heartbeat.service: Unit entered failed state.
Ответ 2
1) Установите пакет supervisor
(более подробные инструкции здесь):
sudo apt-get install supervisor
2) Создайте файл конфигурации для своего демона в /etc/supervisor/conf.d/my_mod.conf
:
[program:my_mod]
directory=/path/to/project/root
environment=ENV_VARIABLE=example,OTHER_ENV_VARIABLE=example2
command=python my_mod.py
autostart=true
autorestart=true
3) Перезагрузите supervisor
для загрузки нового .conf
supervisorctl update
supervisorctl restart my_mod
Ответ 3
Сначала попробуйте следующее в подсказке python.
$ python
>>> import my_mod
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named my_mod
>>>
Исправить 1
Если вы получаете вышеупомянутый вывод, причиной может быть причина разрешения. Предоставьте разрешение для сайтов-пакетов, используя следующее.
sudo chmod -R go+rX /usr/local/lib/python2.7/dist-packages
Исправить 2
Попробуйте экспортировать PYTHONPATH, как показано ниже:
export PYTHONPATH="/usr/.local/lib/python2.7/site-packages"
Исправить 3
Проверьте, есть ли у вас несколько версий python, работающих на одном компьютере.
Если это так, проверьте, включен ли у вас правильный интерпретатор в начале кода, например: #!/usr/bin/python
Ответ 4
У меня такая же проблема. Я понял, что pip install
должна быть специфичной для пользователя.
Поэтому я переключился на root, а затем установил пакеты. После этого он работал.
Однако, я думаю, что указание User=myUser
в файле службы было бы более правильным, однако я хотел, чтобы он запускался с правами root, и я не был уверен, что это произойдет, когда я укажу пользователя.
Надеюсь, это поможет кому-то
Ответ 5
Если вы хотите запустить службу с правами администратора, вам необходимо установить модуль с помощью sudo: sudo pip install my_module
.
Ответ 6
Поскольку ваш скрипт на python выполняется с python3.4
, ваша проблема, скорее всего, заключается в использовании pip
вместо pip3
(или, возможно, sudo -H pip3
).
Но так как вы также спрашиваете конкретно об использовании модулей python из службы systemd, я бы порекомендовал использовать apt
с sudo
, если это вообще возможно, вместо того, чтобы возиться с pip (что печально известно для введения проблем с правами доступа к файлам):
sudo apt install python3-my_module