[英]Cannot get Bash script output in Celery Worker inside Docker Container
我真的在為這個問題拉頭發。 最近我開始研究遠程代碼執行服務。
該服務將以下有效負載發送到 Celery 工作器:
{
"language": "python",
"code": "print('Hello World!')"
}
該服務期望收到代碼的 output。
Celery 工作器在 docker 容器中運行,具有以下Dockerfile :
FROM python:3.9-slim-buster
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONBUFFERED 1
RUN mkdir /worker
WORKDIR /worker
COPY requirements.txt /worker/
RUN /usr/local/bin/python -m pip install --upgrade pip
RUN pip install -r /worker/requirements.txt
COPY . /worker/
對於服務和工作人員,我使用的是 docker-compose 文件:
version: "3"
services:
rabbit:
image: rabbitmq:latest
ports:
- "5672:5672"
api:
build: app/
command: uvicorn remote_coding_compilation_engine.main:app --host 0.0.0.0 --reload
volumes:
- ./app:/app
ports:
- "8000:8000"
worker:
build: worker/
command: watchmedo auto-restart --directory=./ --pattern=*.py --recursive -- celery --app=worker.celery_app worker -c 2 --loglevel=INFO
#celery --app=worker.celery_app worker -c 2 --loglevel=INFO
volumes:
- ./worker:/worker
depends_on:
- api
- rabbit
flower:
image: mher/flower
command: ["flower", "--broker=pyamqp://guest@rabbit//", "--port=8888"]
ports:
- "8888:8888"
depends_on:
- api
- rabbit
- worker
工作人員使用有效負載中給出的代碼創建一個.py文件,然后運行 bash 腳本來執行代碼,代碼 output 應自動從 Z23EEEB4347BDD26BFC6B7EE9A3B75 重定向到out_file 但是我無法獲得 bash 腳本的 output 。
這是 bash 腳本:
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No code running command provided!"
else
eval $@
fi
我將以下 arguments 傳遞給此腳本: python path_to_file
這是運行 bash 腳本的工作代碼:
def execute_code(cls, command: str, out_file_path: str) -> None:
"""
Function which execudes the given command and outputs the result in the given out_file_path
@param command: command to be executed
@param out_file_path: path to the output file
@return None
@raise: FileNotFoundError if the command does not exist
@raise: IOError if the output file cannot be created
@raise: CalledProcessError if the command fails to be executed
"""
try:
logging.info(f"Creating output file: {out_file_path}")
with open(out_file_path, "w+") as out_file_desc:
logging.info(f"Creating process with command: {command} and output_file: {out_file_path}")
os.chmod(cls.EXECUTE_CODE_SCRIPT_PATH, 0o755)
rc = subprocess.call(command, shell=True, stdout=out_file_desc, stderr=out_file_desc)
logging.info(f"Commandmd: {command.split()}")
logging.info(f"Return Code: {rc}")
logging.info(f"OutFile Content: {out_file_desc.read()}")
if rc != 0:
logging.debug(f"Command execution was errored: {out_file_desc.read()}")
raise subprocess.CalledProcessError(rc, command)
except FileNotFoundError as fnf:
logging.error(
f"Command not found: {command}"
)
raise fnf
except IOError as ioe:
logging.error(
f"Could not create output file: {out_file_path}"
)
raise ioe
except subprocess.CalledProcessError as cpe:
logging.error(
f"Process exited with error: {cpe.output}"
)
raise cpe
觀察1。 subprocess.call
中要執行的命令格式/worker/execute_code/code_execute.sh python /worker/tmp/in_files/some_file_name.py
觀察2。 我確信腳本會運行該命令,例如,如果我更改包含要執行的代碼的文件夾的路徑,我會收到“FileNotFound”錯誤。
觀察3。 如果我使用字面意義上的 python <<hardcoded_path>> 而不是“$@”,我可以看到 bash 腳本的 output
觀察4。 運行實體對 output 文件具有 rw 訪問權限。 即使我使用默認的標准輸出,我也無法獲得腳本的 output
我試過的:
任何幫助將不勝感激,謝謝!
我相信您最初的直覺是正確的,根本不需要維護 bash 文件。 如果我正確理解您要執行的操作(執行命令,將 output 寫入文件),則無需維護 bash 腳本或將命令寫入輸入文件即可:
def execute_code(command="print('Hello World')", out_file_path='/home/geo/result.txt'):
with open(out_file_path, 'w+') as f:
subprocess.Popen(["python", "-c", command], stdout=f)
您應該在result.txt
中看到 output 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.