簡體   English   中英

無法在 Celery 容器中的 Bash 腳本 output 中獲取 Worker

[英]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 腳本,我想使用 subprocess.run,但我再次無法獲得 output
  • 如果我使用終端調用腳本,我會得到代碼 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM