Мое приложение (clads) работает на Django и использует Celery для временных и асинхронных задач.К сожалению, я не могу понять некоторые проблемы с разрешениями, которые мешают процессам Celery записывать в журналы приложения Django или манипулировать файлами, созданными приложением Django.Приложение Django запускается в процессе wsgi, и у меня есть несколько файлов конфигурации, которые устанавливают каталог журнала приложения, чтобы процесс wsgi мог писать в него (см. Ниже).
Однако кажется, что процессы сельдерея выполняются от имени другого пользователя, у которого нет разрешения на запись в эти файлы (что он автоматически пытается сделать, когда видит конфигурацию файла журнала - также ниже). Примечание Iпытался изменить это, чтобы работать как WSGI, но не работает).Похоже, что та же самая проблема с разрешениями не позволяет процессу Celery манипулировать временными файлами, созданными приложением Django - требование проекта.
По общему признанию я очень ржавый на операционных системах типа Unix, поэтому я уверен, что упускаю какую-то простую вещь.Я искал этот сайт и другие в течение нескольких дней, и хотя я нашел много постов, которые приблизили меня к этой проблеме, я все еще не могу решить ее.Я подозреваю, что могут быть некоторые дополнительные команды, которые мне нужны в моей конфигурации, чтобы установить разрешения или запустить Celery под другим пользователем.Любая помощь будет принята с благодарностью.Конфигурация проекта и соответствующие файлы кода приведены ниже.Большинство файлов конфигурации были собраны вместе из информации, найденной на этом и других сайтах - извините за то, что не разместили, но не держали достаточно близко записей, чтобы точно знать, откуда они пришли.
Журнальные и Celery части settings.py
#log settings
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(asctime)s - %(levelname)s - %(module)s.%(fileName)s.%(funcName)s %(processName)d %(threadName)d: %(message)s',
},
'simple': {
'format': '%(asctime)s - %(levelname)s: %(message)s'
},
},
'handlers' : {
'django_log_file': {
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
'class': 'logging.FileHandler',
'filename': os.environ.get('DJANGO_LOG_FILE'),
'formatter': 'verbose',
},
'app_log_file': {
'level': os.getenv('CLADS_LOG_LEVEL', 'INFO'),
'class': 'logging.FileHandler',
'filename': os.environ.get('CLADS_LOG_FILE'),
'formatter': 'verbose',
},
},
'loggers': {
'django': {
'handlers': ['django_log_file'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'INFO'),
'propagate': True,
},
'clads': {
'handlers': ['app_log_file'],
'level': os.getenv('CLADS_LOG_LEVEL', 'INFO'),
'propagate': True,
},
},
}
WSGI_APPLICATION = 'clads.wsgi.application'
# celery settings
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend'
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
CELERY_SEND_EVENTS = False
CELERY_BROKER_URL = os.environ.get('BROKER_URL')
tasks.py выдержки LOGGER = logging.getLogger ('clads.pit')
@shared_task(name="archive_pit_file")
def archive_pit_file(tfile_name):
LOGGER.debug('archive_date_file called for ' + tfile_name)
LOGGER.debug('connecting to S3 ...')
s3 = boto3.client('s3')
file_fname = os.path.join(settings.TEMP_FOLDER, tfile_name)
LOGGER.debug('reading temp file from ' + file_fname)
s3.upload_file(file_fname, settings.S3_ARCHIVE, tfile_name)
LOGGER.debug('cleaning up temp files ...')
#THIS LINE CAUSES PROBLEMS BECAUSE THE CELERY PROCESS DOES'T HAVE
#PERMISSION TO REMOVE TEH WSGI OWNED FILE
os.remove(file_fname)
logging.config
commands:
01_change_permissions:
command: chmod g+s /opt/python/log
02_change_owner:
command: chown root:wsgi /opt/python/log
99_celery.config
container_commands:
04_celery_tasks:
command: "cat .ebextensions/files/celery_configuration.txt > /opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_celeryd.sh && chmod 744 /opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_celeryd.sh"
leader_only: true
05_celery_tasks_run:
command: "/opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_celeryd.sh"
leader_only: true
celery_configuration.txt
#!/usr/bin/env bash
# Get django environment variables
celeryenv=`cat /opt/python/current/env | tr '\n' ',' | sed 's/%/%%/g' | sed 's/export //g' | sed 's/$PATH/%(ENV_PATH)s/g' | sed 's/$PYTHONPATH//g' | sed 's/$LD_LIBRARY_PATH//g'`
celeryenv=${celeryenv%?}
# Create celery configuraiton script
celeryconf="[program:celeryd-worker]
; Set full path to celery program if using virtualenv
command=/opt/python/run/venv/bin/celery worker -A clads -b <broker_url> --loglevel=INFO --without-gossip --without-mingle --without-heartbeat
directory=/opt/python/current/app
user=nobody
numprocs=1
stdout_logfile=/var/log/celery-worker.log
stderr_logfile=/var/log/celery-worker.log
autostart=true
autorestart=true
startsecs=10
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
; When resorting to send SIGKILL to the program to terminate it
; send SIGKILL to its whole process group instead,
; taking care of its children as well.
killasgroup=true
; if rabbitmq is supervised, set its priority higher
; so it starts first
priority=998
environment=$celeryenv
[program:celeryd-beat]
; Set full path to celery program if using virtualenv
command=/opt/python/run/venv/bin/celery beat -A clads -b <broker_url> --loglevel=INFO --workdir=/tmp
directory=/opt/python/current/app
user=nobody
numprocs=1
stdout_logfile=/var/log/celery-beat.log
stderr_logfile=/var/log/celery-beat.log
autostart=true
autorestart=true
startsecs=10
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
; When resorting to send SIGKILL to the program to terminate it
; send SIGKILL to its whole process group instead,
; taking care of its children as well.
killasgroup=true
; if rabbitmq is supervised, set its priority higher
; so it starts first
priority=998
environment=$celeryenv"
# Create the celery supervisord conf script
echo "$celeryconf" | tee /opt/python/etc/celery.conf
# Add configuration script to supervisord conf (if not there already)
if ! grep -Fxq "[include]" /opt/python/etc/supervisord.conf
then
echo "[include]" | tee -a /opt/python/etc/supervisord.conf
echo "files: celery.conf" | tee -a /opt/python/etc/supervisord.conf
fi
# Reread the supervisord config
supervisorctl -c /opt/python/etc/supervisord.conf reread
# Update supervisord in cache without restarting all services
supervisorctl -c /opt/python/etc/supervisord.conf update
# Start/Restart celeryd through supervisord
supervisorctl -c /opt/python/etc/supervisord.conf restart celeryd-worker
supervisorctl -c /opt/python/etc/supervisord.conf restart celeryd-beat